aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/Makefile21
-rw-r--r--lib/ssh/doc/src/Makefile19
-rw-r--r--lib/ssh/doc/src/book.xml19
-rw-r--r--lib/ssh/doc/src/introduction.xml201
-rw-r--r--lib/ssh/doc/src/notes.xml588
-rw-r--r--lib/ssh/doc/src/part_notes.xml19
-rw-r--r--lib/ssh/doc/src/ref_man.xml23
-rw-r--r--lib/ssh/doc/src/ssh.xml629
-rw-r--r--lib/ssh/doc/src/ssh_app.xml343
-rw-r--r--lib/ssh/doc/src/ssh_channel.xml315
-rw-r--r--lib/ssh/doc/src/ssh_client_key_api.xml117
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml527
-rw-r--r--lib/ssh/doc/src/ssh_server_key_api.xml98
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml736
-rw-r--r--lib/ssh/doc/src/ssh_sftpd.xml75
-rw-r--r--lib/ssh/doc/src/usersguide.xml26
-rw-r--r--lib/ssh/doc/src/using_ssh.xml227
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps3315
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps2557
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt1232
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps2853
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt1627
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps3511
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt1962
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt2130
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps3205
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt1624
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps1881
-rw-r--r--lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt896
-rw-r--r--lib/ssh/examples/Makefile19
-rw-r--r--lib/ssh/examples/ssh_device.erl19
-rw-r--r--lib/ssh/examples/ssh_sample_cli.erl19
-rw-r--r--lib/ssh/src/Makefile101
-rw-r--r--lib/ssh/src/ssh.app.src1
-rw-r--r--lib/ssh/src/ssh.appup.src19
-rw-r--r--lib/ssh/src/ssh.erl398
-rw-r--r--lib/ssh/src/ssh.hrl44
-rw-r--r--lib/ssh/src/ssh_acceptor.erl32
-rw-r--r--lib/ssh/src/ssh_acceptor_sup.erl43
-rw-r--r--lib/ssh/src/ssh_app.erl21
-rw-r--r--lib/ssh/src/ssh_auth.erl369
-rw-r--r--lib/ssh/src/ssh_auth.hrl22
-rw-r--r--lib/ssh/src/ssh_bits.erl27
-rw-r--r--lib/ssh/src/ssh_channel.erl19
-rw-r--r--lib/ssh/src/ssh_channel_sup.erl21
-rw-r--r--lib/ssh/src/ssh_cli.erl70
-rw-r--r--lib/ssh/src/ssh_client_key.erl19
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl19
-rw-r--r--lib/ssh/src/ssh_connect.hrl22
-rw-r--r--lib/ssh/src/ssh_connection.erl76
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl868
-rw-r--r--lib/ssh/src/ssh_connection_sup.erl21
-rw-r--r--lib/ssh/src/ssh_daemon_channel.erl19
-rw-r--r--lib/ssh/src/ssh_file.erl113
-rw-r--r--lib/ssh/src/ssh_info.erl30
-rw-r--r--lib/ssh/src/ssh_io.erl19
-rw-r--r--lib/ssh/src/ssh_math.erl41
-rw-r--r--lib/ssh/src/ssh_message.erl198
-rw-r--r--lib/ssh/src/ssh_no_io.erl21
-rw-r--r--lib/ssh/src/ssh_server_key.erl19
-rw-r--r--lib/ssh/src/ssh_server_key_api.erl19
-rw-r--r--lib/ssh/src/ssh_sftp.erl50
-rw-r--r--lib/ssh/src/ssh_sftpd.erl41
-rw-r--r--lib/ssh/src/ssh_sftpd_file.erl19
-rw-r--r--lib/ssh/src/ssh_sftpd_file_api.erl21
-rw-r--r--lib/ssh/src/ssh_shell.erl19
-rw-r--r--lib/ssh/src/ssh_subsystem_sup.erl19
-rw-r--r--lib/ssh/src/ssh_sup.erl19
-rw-r--r--lib/ssh/src/ssh_system_sup.erl83
-rw-r--r--lib/ssh/src/ssh_transport.erl1352
-rw-r--r--lib/ssh/src/ssh_transport.hrl122
-rw-r--r--lib/ssh/src/ssh_userauth.hrl19
-rw-r--r--lib/ssh/src/ssh_xfer.erl19
-rw-r--r--lib/ssh/src/ssh_xfer.hrl19
-rw-r--r--lib/ssh/src/sshc_sup.erl19
-rw-r--r--lib/ssh/src/sshd_sup.erl46
-rw-r--r--lib/ssh/test/Makefile40
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_server.erl21
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_encode_decode.erl21
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_subsys.erl21
-rw-r--r--lib/ssh/test/ssh.spec11
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE.erl376
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa5
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key (renamed from lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key)0
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub (renamed from lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub)0
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl1340
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_bench.spec1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE.erl539
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa2565
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa3846
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa5217
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key2565
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key3846
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key5217
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub1
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl177
-rw-r--r--lib/ssh/test/ssh_echo_server.erl19
-rw-r--r--lib/ssh/test/ssh_key_cb.erl45
-rw-r--r--lib/ssh/test/ssh_key_cb_options.erl44
-rw-r--r--lib/ssh/test/ssh_options_SUITE.erl1191
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_peername_sockname_server.erl21
-rw-r--r--lib/ssh/test/ssh_property_test_SUITE.erl21
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl716
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test3
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli3
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_relay.erl407
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE.erl254
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl419
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt16384
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f11
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f21
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt1
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt1
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl36
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl26
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl19
-rw-r--r--lib/ssh/test/ssh_sup_SUITE.erl193
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/test/ssh_test_lib.erl379
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl437
-rw-r--r--lib/ssh/test/ssh_trpt_test_lib.erl772
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE.erl587
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt1
-rw-r--r--lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt1
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE.erl207
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa13
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa15
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts1
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key13
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub11
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key16
-rw-r--r--lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub5
-rw-r--r--lib/ssh/vsn.mk3
191 files changed, 29198 insertions, 33148 deletions
diff --git a/lib/ssh/Makefile b/lib/ssh/Makefile
index b8c7eebcc1..839aada22f 100644
--- a/lib/ssh/Makefile
+++ b/lib/ssh/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2010. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
-#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# %CopyrightEnd%
#
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index 0e79d9979f..c0707f8004 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2012. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# 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
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# %CopyrightEnd%
#
diff --git a/lib/ssh/doc/src/book.xml b/lib/ssh/doc/src/book.xml
index c031d872d7..33b1e0036b 100644
--- a/lib/ssh/doc/src/book.xml
+++ b/lib/ssh/doc/src/book.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml
index b42910cb34..187d458092 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -9,47 +9,198 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>Introduction</title>
<prepared>OTP team</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>introduction.xml</file>
</header>
-
+ <p>SSH is a protocol for secure remote logon and
+ other secure network services over an insecure network.</p>
<section>
- <title>Purpose</title>
+ <title>Scope and Purpose</title>
- <p>Secure Shell (SSH) is a protocol for secure remote login and
- other secure network services over an insecure network. SSH
- provides a single, full-duplex, byte-oriented connection between
+ <p>SSH provides a single, full-duplex, and byte-oriented connection between
client and server. The protocol also provides privacy, integrity,
- server authentication and man-in-the-middle protection.</p>
-
- <p>The Erlang SSH application is an implementation of the SSH
- protocol in Erlang which offers API functions to write customized
- SSH clients and servers as well as making the Erlang shell
- available via SSH. Also included in the SSH application are an
- SFTP (SSH File Transfer Protocol) client <seealso
- marker="ssh_sftp">ssh_sftp</seealso> and server <seealso
- marker="ssh_sftp">ssh_sftpd</seealso>.</p>
+ server authentication, and man-in-the-middle protection.</p>
+
+ <p>The <c>ssh</c> application is an implementation of the SSH Transport, Connection and Authentication
+ Layer Protocols in Erlang. It provides the following:</p>
+ <list type="bulleted">
+ <item>API functions to write customized SSH clients and servers applications</item>
+ <item>The Erlang shell available over SSH</item>
+ <item>An SFTP client (<seealso marker="ssh_sftp">ssh_sftp</seealso>)
+ and server (<seealso marker="ssh_sftp">ssh_sftpd</seealso>)</item>
+ </list>
</section>
<section>
<title>Prerequisites</title>
- <p>It is assumed that the reader is familiar with the concepts of <seealso marker="doc/design_principles:des_princ">OTP</seealso>
- and has a basic understanding of <url href="http://en.wikipedia.org/wiki/Public-key_cryptography">public keys</url>.</p>
+ <p>It is assumed that the reader is familiar with the Erlang programming language,
+ concepts of <em>OTP</em>, and has a basic understanding of <em>public keys</em>.</p>
+ </section>
+
+<section>
+ <title>SSH Protocol Overview</title>
+
+ <p>Conceptually, the SSH protocol can be partitioned into four
+ layers:</p>
+
+ <image file="SSH_protocols.png">
+ <icaption>SSH Protocol Architecture</icaption>
+ </image>
+
+ <section>
+ <title>Transport Protocol</title>
+
+ <p>The SSH Transport Protocol is a secure, low-level transport.
+ It provides strong encryption, cryptographic host
+ authentication, and integrity protection. A minimum of
+ Message Authentication Code (MAC) and encryption
+ algorithms are supported. For details, see the
+ <seealso marker="ssh">ssh(3)</seealso> manual page in <c>ssh</c>.</p>
+ </section>
+
+ <section>
+ <title>Authentication Protocol</title>
+
+ <p>The SSH Authentication Protocol is a general-purpose user
+ authentication protocol run over the SSH Transport Layer
+ Protocol. The <c>ssh</c> application supports user authentication as follows:
+ </p>
+ <list type="bulleted">
+ <item>
+ Using public key technology. RSA and DSA, X509-certificates
+ are not supported.
+ </item>
+ <item>
+ Using keyboard-interactive authentication.
+ This is suitable for interactive authentication methods
+ that do not need any special software support on the client side.
+ Instead, all authentication data is entered from the keyboard.
+ </item>
+ <item>
+ Using a pure password-based authentication scheme.
+ Here, the plain text password is encrypted before sent
+ over the network.
+ </item>
+ </list>
+ <p>Several configuration options for
+ authentication handling are available in
+ <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso>
+ and <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</p>
+ <p>
+ The public key handling can be customized by implementing
+ the following behaviours from <c>ssh</c>:</p>
+ <list type="bulleted">
+ <item>Module
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso>.
+ </item>
+ <item>Module
+ <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Connection Protocol</title>
+
+ <p>The SSH Connection Protocol provides application-support
+ services over the transport pipe, for example, channel multiplexing,
+ flow control, remote program execution, signal propagation, and
+ connection forwarding. Functions for handling the SSH
+ Connection Protocol can be found in the module <seealso
+ marker="ssh_connection">ssh_connection</seealso> in <c>ssh</c>.
+ </p>
+ </section>
+
+ <section>
+ <title>Channels</title>
+
+ <p>All terminal sessions, forwarded connections, and so on, are
+ channels. Multiple channels are multiplexed into a single
+ connection. All channels are flow-controlled. This means that no
+ data is sent to a channel peer until a message is received to
+ indicate that window space is available.
+ The <em>initial window size</em> specifies how many bytes of channel
+ data that can be sent to the channel peer without adjusting the
+ window. Typically, an SSH client opens a channel, sends data (commands),
+ receives data (control information), and then closes the channel.
+ The <seealso marker="ssh_channel">ssh_channel</seealso> behaviour
+ handles generic parts of SSH channel management. This makes it easy
+ to write your own SSH client/server processes that use flow-control
+ and thus opens for more focus on the application logic.
+ </p>
+
+ <p>Channels come in the following three flavors:</p>
+
+ <list type="bulleted">
+ <item><em>Subsystem</em> - Named services that can be run as
+ part of an SSH server, such as SFTP <seealso
+ marker="ssh_sftpd">(ssh_sftpd)</seealso>, that is built into the
+ SSH daemon (server) by default, but it can be disabled. The Erlang <c>ssh</c>
+ daemon can be configured to run any Erlang-
+ implemented SSH subsystem.
+ </item>
+ <item><em>Shell</em> - Interactive shell. By default the
+ Erlang daemon runs the Erlang shell. The shell can be customized by
+ providing your own read-eval-print loop. You can also provide your
+ own Command-Line Interface (CLI) implementation,
+ but that is much more work.
+ </item>
+ <item><em>Exec</em> - One-time remote execution of commands. See function
+ <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>
+ for more information.</item>
+ </list>
+ </section>
+
+
+
</section>
+ <section>
+ <title>Where to Find More Information</title>
+ <p>
+ For detailed information about the SSH protocol, refer to the
+ following Request for Comments(RFCs):
+ </p>
+
+ <list type="bulleted">
+ <item><url href="http://www.ietf.org/rfc/rfc4250.txt">RFC 4250</url> -
+ Protocol Assigned Numbers</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4251.txt">RFC 4251</url> -
+ Protocol Architecture</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4252.txt">RFC 4252</url> -
+ Authentication Protocol</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4253.txt">RFC 4253</url> -
+ Transport Layer Protocol</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> -
+ Connection Protocol</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4255.txt">RFC 4255</url> -
+ Key Fingerprints</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4344.txt">RFC 4344</url> -
+ Transport Layer Encryption Modes</item>
+ <item><url href="http://www.ietf.org/rfc/rfc4716.txt">RFC 4716</url> -
+ Public Key File Format</item>
+ </list>
+ </section>
</chapter>
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index c77ee1e77a..75e1615c09 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,20 +4,21 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2014</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -29,6 +30,567 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.2.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The authentication method 'keyboard-interactive' failed
+ in the Erlang client when the server after successful
+ authentication continued by asking for zero more
+ passwords.</p>
+ <p>
+ Own Id: OTP-13225</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Better error handling in ssh_file. There was some rare
+ errors when a NFS-mounted file was opened by ssh_file and
+ then remotely deleted during reading. That caused an
+ endless loop. </p>
+ <p>
+ That bug is now fixed.</p>
+ <p>
+ Own Id: OTP-12699 Aux Id: OTP-11688 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug in the compression algorithm
+ <p>
+ Own Id: OTP-12759</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to start more than one daemon with a
+ file descriptor given in option fd. Each daemon must of
+ course have a unique file descriptor.</p>
+ <p>
+ Own Id: OTP-12966 Aux Id: seq12945 </p>
+ </item>
+ <item>
+ <p>
+ Fixed a bug that caused the option <c>dh_gex_limit</c> to
+ be ignored.</p>
+ <p>
+ Own Id: OTP-13029</p>
+ </item>
+ <item>
+ <p>
+ A problem is fixed with the <c>ssh:connect</c> option
+ <c>pref_public_key_algs</c> specifying user keys.</p>
+ <p>
+ Own Id: OTP-13158</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Document updates in the ssh reference manual: app doc
+ file and ssh_connection.</p>
+ <p>
+ Own Id: OTP-12003</p>
+ </item>
+ <item>
+ <p>
+ The authorization phase is made stateful to prevent ssh
+ acting on messages sent in wrong order.</p>
+ <p>
+ Own Id: OTP-12787</p>
+ </item>
+ <item>
+ <p>
+ Testcases for bad message lengths and for bad subfield
+ lengths added.</p>
+ <p>
+ Own Id: OTP-12792 Aux Id: Codenomicon #5214, 6166 </p>
+ </item>
+ <item>
+ <p>
+ The 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384' and
+ 'ecdsa-sha2-nistp521' signature algorithms for ssh are
+ implemented. See RFC 5656.</p>
+ <p>
+ Own Id: OTP-12936</p>
+ </item>
+ <item>
+ <p>
+ The crypto algorithms 'aes192-ctr' and 'aes256-ctr' are
+ implemented. See RFC 4344.</p>
+ <p>
+ Own Id: OTP-12939</p>
+ </item>
+ <item>
+ <p>
+ The ciphers and macs AEAD_AES_128_GCM and
+ AEAD_AES_256_GCM are implemented but not enabled per
+ default. See the SSH App Reference Manual and RFC5647 for
+ details.</p>
+ <p>
+ The ciphers [email protected] and
+ [email protected] are also implemented and available
+ in the default configuration.</p>
+ <p>
+ Own Id: OTP-13018</p>
+ </item>
+ <item>
+ <p>
+ The ssh:daemon option dh_gex_groups is extended to read a
+ user provided ssh moduli file with generator-modulus
+ pairs. The file is in openssh format.</p>
+ <p>
+ Own Id: OTP-13052 Aux Id: OTP-13054 </p>
+ </item>
+ <item>
+ <p>
+ There is now a file (public_key/priv/moduli) which lists
+ size-generator-modulus triples. The purpose is to give
+ servers the possibility to select the crypto primes
+ randomly among a list of pregenerated triples. This
+ reduces the risk for some attacks on diffie-hellman
+ negotiation.</p>
+ <p>
+ See the reference manual for public_key:dh_gex_group/4
+ where the handling of this is described.</p>
+ <p>
+ The ssh server (ssh:daemon) uses this.</p>
+ <p>
+ Own Id: OTP-13054 Aux Id: OTP-13052 </p>
+ </item>
+ <item>
+ <p>
+ The ssh:daemon option pwdfun now also takes a fun/4. This
+ enables the user to 1) check userid-password in another
+ way than the builtin algorithm, 2) implement rate
+ limiting per user or source IP or IP+Port, and 3)
+ implement blocking of missbehaving peers.</p>
+ <p>
+ The old fun/2 still works as previously.</p>
+ <p>
+ Own Id: OTP-13055 Aux Id: OTP-13053 </p>
+ </item>
+ <item>
+ <p>
+ There is now a new option to make the server limit the
+ size range of moduli available for the diffie-hellman
+ group exchange negotiation. See option <c>
+ {dh_gex_limits,{Min,Max}}</c> in ssh:daemon/3.</p>
+ <p>
+ Own Id: OTP-13066</p>
+ </item>
+ <item>
+ <p>
+ Ecdh key exchange now validates compressed and
+ uncompressed keys as defined in rfc5656</p>
+ <p>
+ Own Id: OTP-13067</p>
+ </item>
+ <item>
+ <p>
+ Search order for the .ssh directory are changed so
+ <c>$HOME</c> is tried before
+ <c>init:get_argument(home)</c>.</p>
+ <p>
+ Own Id: OTP-13109</p>
+ </item>
+ <item>
+ <p>
+ The sftp receive window handling is optimized so it will
+ not update the remote end too often. This makes "sftp
+ mget" considerable faster.</p>
+ <p>
+ Own Id: OTP-13130</p>
+ </item>
+ <item>
+ <p>
+ The option <c>key_cb</c> is extended to take an optional
+ list that is passed to the callback module as an option.
+ With this it is possible to have different keys depending
+ on which host that is connected. Another possibility is
+ to write a callback module that fetches keys etc from a
+ database.</p>
+ <p>
+ Thanks to Vipin Nair.</p>
+ <p>
+ Own Id: OTP-13156</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.3</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ SSH_MSG_KEX_DH_GEX_REQUEST_OLD implemented to make PuTTY
+ work with erl server.</p>
+ <p>
+ Own Id: OTP-13140</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add a 1024 group to the list of key group-exchange groups</p>
+ <p>
+ Own Id: OTP-13046</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new option <c>max_channels</c> limits the number of
+ channels with active server-side subsystems that are
+ accepted.</p>
+ <p>
+ Own Id: OTP-13036</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Send an understandable disconnect message when the key
+ exchange phase can't find a common algorithm. There are
+ also some test cases added.</p>
+ <p>
+ Own Id: OTP-11531</p>
+ </item>
+ <item>
+ <p>
+ The third parameter in <c>ssh_sftp:write_file</c> is now
+ accepting iolists again. Unicode handling adjusted.</p>
+ <p>
+ Own Id: OTP-12853 Aux Id: seq12891 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ First part of ssh test suite re-organization and
+ extension.</p>
+ <p>
+ Own Id: OTP-12230</p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithms 'ecdh-sha2-nistp256',
+ 'ecdh-sha2-nistp384' and 'ecdh-sha2-nistp521' are
+ implemented. See RFC 5656.</p>
+ <p>
+ This raises the security level considerably.</p>
+ <p>
+ Own Id: OTP-12622 Aux Id: OTP-12671, OTP-12672 </p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithm 'diffie-hellman-group14-sha1'
+ is implemented. See RFC 4253.</p>
+ <p>
+ This raises the security level.</p>
+ <p>
+ Own Id: OTP-12671 Aux Id: OTP-12672, OTP-12622 </p>
+ </item>
+ <item>
+ <p>
+ The key exchange algorithms
+ 'diffie-hellman-group-exchange-sha1' and
+ 'diffie-hellman-group-exchange-sha256' are implemented.
+ See RFC 4419.</p>
+ <p>
+ This raises the security level.</p>
+ <p>
+ Own Id: OTP-12672 Aux Id: OTP-12671, OTP-12622 </p>
+ </item>
+ <item>
+ <p>
+ Adding random length extra padding as recommended in RFC
+ 4253 section 6.</p>
+ <p>
+ Own Id: OTP-12831</p>
+ </item>
+ <item>
+ <p>
+ New test library for low-level protocol testing. There is
+ also a test suite using it for some preliminary tests.
+ The intention is to build on that for more testing of
+ individual ssh messages. See
+ <c>lib/ssh/test/ssh_trpt_test_lib.erl</c> and
+ <c>ssh_protocol_SUITE.erl</c> in the same directory.</p>
+ <p>
+ Own Id: OTP-12858</p>
+ </item>
+ <item>
+ <p>
+ Increased default values for
+ diffie-hellman-group-exchange-sha* to Min = 1024, N =
+ 6144, Max = 8192.</p>
+ <p>
+ Added 6144 and 8192 bit default gex groups.</p>
+ <p>
+ Own Id: OTP-12937</p>
+ </item>
+ <item>
+ <p>
+ The mac algorithm 'hmac-sha2-512' is implemented. See RFC
+ 6668.</p>
+ <p>
+ Own Id: OTP-12938</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.0</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Ssh crashed if a message was sent on a channel with
+ packet_size = 0.</p>
+ <p>
+ A new option for ssh:daemon is also introduced:
+ <c>minimal_remote_max_packet_size</c>. This option sets
+ the least max packet size declaration that the daemon
+ will accept from a client. The default value is 0 to
+ maintain compatibility with OpenSSH and the rfc:s.</p>
+ <p>
+ Own Id: OTP-12645 Aux Id: seq12816 </p>
+ </item>
+ <item>
+ <p>
+ Included test of the 'e' and 'f' parameters in
+ diffie-hellman key exchange as specified in rfc 4253
+ section 8.</p>
+ <p>
+ Own Id: OTP-12649</p>
+ </item>
+ <item>
+ <p>
+ Fixes the bug that once the <c>rekey_limit</c> bytes (by
+ default, 1GB) had been transmitted the connection was
+ rekeyed every minute, not after the next transferred
+ 'rekey_limit' chunk.</p>
+ <p>
+ Thanks to Simon Cornish for the report and the fix!</p>
+ <p>
+ Own Id: OTP-12692</p>
+ </item>
+ <item>
+ <p>
+ Fixes a bug that causes an SFTP connection to always fail
+ when {timeout, Timeout} option is used with
+ ssh_sftp:start_channel.</p>
+ <p>
+ Thanks to Simon Cornish</p>
+ <p>
+ Own Id: OTP-12708</p>
+ </item>
+ <item>
+ <p>
+ Fix various ssh key exchange problems.</p>
+ <p>
+ Thanks to Simon Cornish</p>
+ <p>
+ Own Id: OTP-12760 Aux Id: <url
+ href="https://github.com/erlang/otp/pull/715">pull req
+ 715</url> </p>
+ </item>
+ <item>
+ <p>
+ The options <c>system_dir</c> and <c>user_dir</c> assumes
+ that the value is a path to a directory which is
+ readable. This is now checked early, so <c>ssh:daemon</c>
+ and <c>ssh:connect</c> will fail with an error message
+ immediately.</p>
+ <p>
+ Own Id: OTP-12788</p>
+ </item>
+ <item>
+ <p>
+ A daemon now checks that a client doesn't try to
+ authorize with methods not in the option auth_methods.</p>
+ <p>
+ Own Id: OTP-12790</p>
+ </item>
+ <item>
+ <p>
+ Disconnectfun now should trigger on all disconnects.</p>
+ <p>
+ Own Id: OTP-12811</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Better usage of binary matching in ssh_auth.erl and
+ ssh_message.erl</p>
+ <p>
+ Own Id: OTP-11697</p>
+ </item>
+ <item>
+ <p>
+ A new option 'preferred_algorithms' is available for
+ <c>ssh:daemon</c> and <c>ssh:connect</c>.</p>
+ <p>
+ This option defines the algorithms presented to the peer
+ in the algorithm negotiation phase of the ssh protocol. </p>
+ <p>
+ The default list can be obtained from the new function
+ <c>ssh:default_algorithms/0</c>.</p>
+ <p>
+ *** INCOMPATIBILITY with removed undocumented options
+ 'role' and 'compression' ***</p>
+ <p>
+ Own Id: OTP-12029</p>
+ </item>
+ <item>
+ <p>
+ The internal group to user_drv protocol has been changed
+ to be synchronous in order to guarantee that output sent
+ to a process implementing the user_drv protocol is
+ printed before replying. This protocol is used by the
+ standard_output device and the ssh application when
+ acting as a client. </p>
+ <p>
+ This change changes the previous unlimited buffer when
+ printing to standard_io and other devices that end up in
+ user_drv to 1KB.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12240</p>
+ </item>
+ <item>
+ <p>
+ If ssh_connection:subsystem/4 fails we do not want to
+ crash but rather terminate gracefully.</p>
+ <p>
+ Own Id: OTP-12648 Aux Id: seq12834 </p>
+ </item>
+ <item>
+ <p>
+ New option <c>id_string</c> for <c>ssh:daemon</c> and
+ <c>ssh:connect</c> for limiting banner grabbing attempts.</p>
+ <p>
+ The possible values are: <c>{id_string,string()}</c> and
+ <c>{id_string,random}</c>. The latter will make ssh
+ generate a random nonsence id-string for each new
+ connection.</p>
+ <p>
+ Own Id: OTP-12659</p>
+ </item>
+ <item>
+ <p>
+ To enable the ssh daemon to run in a virtualized
+ environment, where there can be more that one server that
+ has the same ip-address and port, we add a new option
+ profile.</p>
+ <p>
+ Own Id: OTP-12675</p>
+ </item>
+ <item>
+ <p>
+ Upgrade test suite added.</p>
+ <p>
+ Own Id: OTP-12676</p>
+ </item>
+ <item>
+ <p>
+ A new option for handling the SSH_MSG_DEBUG message's
+ printouts. A fun could be given in the options that will
+ be called whenever the SSH_MSG_DEBUG message arrives.
+ This enables the user to format the printout or just
+ discard it.</p>
+ <p>
+ Own Id: OTP-12738 Aux Id: seq12860 </p>
+ </item>
+ <item>
+ <p>
+ Testcase improvements and corrections:</p>
+ <p>
+ * Add testcases for the <c>disconnectfun</c> option on
+ both server and client sides</p>
+ <p>
+ * Timeout testcases adjusted for slow machines where they
+ sometimes failed</p>
+ <p>
+ Own Id: OTP-12786</p>
+ </item>
+ <item>
+ <p>
+ The option <c>disconnectfun</c> can now be used both on
+ the client and server side.</p>
+ <p>
+ Own Id: OTP-12789</p>
+ </item>
+ <item>
+ <p>
+ A new option unknown_msgfun/2 for ssh:connect and
+ ssh:daemon for handling unknown messages. With the option
+ it is possible to intercept before an INFO log message is
+ generated.</p>
+ <p>
+ One usage is to filter out messages that are not wanted
+ in the error logger as info reports. An example of such a
+ message is the 'etimedout' tcp error message that will be
+ received if a connection has keep_alive and the peer is
+ restarted.</p>
+ <p>
+ Own Id: OTP-12813 Aux Id: seq12881 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 3.2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -41,13 +603,13 @@
</item>
<item>
<p>
- Made Codenomicon Defensics test suite pass: <list>
+ Made Codenomicon Defensics test suite pass:</p> <list>
<item>limit number of algorithms in kexinit
message</item> <item>check 'e' and 'f' parameters in
kexdh</item> <item>implement 'keyboard-interactive' user
authentication on server side</item> <item> return plain
text message to bad version exchange message</item>
- </list></p>
+ </list>
<p>
Own Id: OTP-12784</p>
</item>
diff --git a/lib/ssh/doc/src/part_notes.xml b/lib/ssh/doc/src/part_notes.xml
index c5cc163717..664cadce57 100644
--- a/lib/ssh/doc/src/part_notes.xml
+++ b/lib/ssh/doc/src/part_notes.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
diff --git a/lib/ssh/doc/src/ref_man.xml b/lib/ssh/doc/src/ref_man.xml
index 55339298e8..4a2f043948 100644
--- a/lib/ssh/doc/src/ref_man.xml
+++ b/lib/ssh/doc/src/ref_man.xml
@@ -8,16 +8,17 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
@@ -28,8 +29,8 @@
<file>ref_man.xml</file>
</header>
<description>
- <p>The SSH application is an erlang implementation of the
- secure shell protocol (SSH) as defined by RFC 4250 - 4254</p>
+ <p>The <c>ssh</c> application is an Erlang implementation of the
+ Secure Shell Protocol (SSH) as defined by RFC 4250 - 4254.</p>
</description>
<xi:include href="ssh_app.xml"/>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index 501668ca78..850557444d 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,72 +4,118 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2014</year>
+ <year>2004</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh</title>
+ <prepared></prepared>
+ <docno></docno>
<date>2007-10-06</date>
+ <rev></rev>
</header>
<module>ssh</module>
- <modulesummary>Main API of the SSH application</modulesummary>
+ <modulesummary>Main API of the ssh application</modulesummary>
<description>
- <p>Interface module for the SSH application. </p>
+ <p>Interface module for the <c>ssh</c> application.</p>
+ <p>See <seealso marker="ssh:SSH_app#supported">ssh(6)</seealso> for details of supported version,
+ algorithms and unicode support.</p>
</description>
- <section>
- <title>SSH</title>
-
- <list type="bulleted">
- <item>SSH requires the crypto and public_key applications.</item>
- <item>Supported SSH version is 2.0 </item>
- <item>Supported MAC algorithms: hmac-sha2-256 and hmac-sha1</item>
- <item>Supported encryption algorithms: aes128-ctr, aes128-cb and 3des-cbc</item>
- <item>Supports unicode filenames if the emulator and the underlaying OS supports it. See the DESCRIPTION section in <seealso marker="kernel:file">file</seealso> for information about this subject</item>
- <item>Supports unicode in shell and cli</item>
- </list>
-
+ <section>
+ <title>OPTIONS</title>
+ <p>The exact behaviour of some functions can be adjusted with the use of options which are documented together
+ with the functions. Generally could each option be used at most one time in each function call. If given two or more
+ times, the effect is not predictable unless explicitly documented.</p>
+ <p>The options are of different kinds:</p>
+ <taglist>
+ <tag>Limits</tag>
+ <item><p>which alters limits in the system, for example number of simultaneous login attempts.</p></item>
+
+ <tag>Timeouts</tag>
+ <item><p>which give some defined behaviour if too long time elapses before a given event or action,
+ for example time to wait for an answer.</p></item>
+
+ <tag>Callbacks</tag>
+ <item><p>which gives the caller of the function the possibility to execute own code on some events,
+ for example calling an own logging function or to perform an own login function</p></item>
+
+ <tag>Behaviour</tag>
+ <item><p>which changes the systems behaviour.</p></item>
+ </taglist>
</section>
-
+
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
<p>Type definitions that are used more than once in
- this module and/or abstractions to indicate the intended use of the data
- type:</p>
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = [byte()]</c></p>
- <p><c>ssh_daemon_ref() - opaque to the user
- returned by ssh:daemon/[1,2,3]</c></p>
- <p><c>ssh_connection_ref() - opaque to the user
- returned by ssh:connect/3</c></p>
- <p><c>ip_address() - inet::ip_address()</c></p>
- <p><c>subsystem_spec() = {subsystem_name(),
- {channel_callback(), channel_init_args()}} </c></p>
- <p><c>subsystem_name() = string() </c></p>
- <p><c>channel_callback() = atom() - Name of the erlang module
- implementing the subsystem using the ssh_channel behavior see</c>
- <seealso marker="ssh_channel">ssh_channel(3)</seealso></p>
- <p><c>channel_init_args() = list()</c></p>
- </section>
+ this module, or abstractions to indicate the intended use of the data
+ type, or both:</p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>ssh_daemon_ref() =</c></tag>
+ <item><p>opaque() -
+ as returned by <c>ssh:daemon/[1,2,3]</c></p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() - as returned by <c>ssh:connect/3</c></p></item>
+ <tag><c>ip_address() =</c></tag>
+ <item><p><c>inet::ip_address</c></p></item>
+ <tag><c>subsystem_spec() =</c></tag>
+ <item><p><c>{subsystem_name(),
+ {channel_callback(), channel_init_args()}}</c></p></item>
+ <tag><c>subsystem_name() =</c></tag>
+ <item><p><c>string()</c></p></item>
+ <tag><c>channel_callback() =</c></tag>
+ <item><p><c>atom()</c> - Name of the Erlang module
+ implementing the subsystem using the <c>ssh_channel</c> behavior, see
+ <seealso marker="ssh_channel">ssh_channel(3)</seealso></p></item>
+ <tag><c>key_cb() =</c></tag>
+ <item>
+ <p><c>atom() | {atom(), list()}</c></p>
+ <p><c>atom()</c> - Name of the erlang module implementing the behaviours
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> or
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> as the
+ case maybe.</p>
+ <p><c>list()</c> - List of options that can be passed to the callback module.</p>
+ </item>
+ <tag><c>channel_init_args() =</c></tag>
+ <item><p><c>list()</c></p></item>
+
+ <tag><c>algs_list() =</c></tag>
+ <item><p><c>list( alg_entry() )</c></p></item>
+
+ <tag><c>alg_entry() =</c></tag>
+ <item><p><c>{kex, simple_algs()} | {public_key, simple_algs()} | {cipher, double_algs()} | {mac, double_algs()} | {compression, double_algs()}</c></p></item>
+
+ <tag><c>simple_algs() =</c></tag>
+ <item><p><c>list( atom() )</c></p></item>
+
+ <tag><c>double_algs() =</c></tag>
+ <item><p><c>[{client2serverlist,simple_algs()},{server2client,simple_algs()}] | simple_algs()</c></p></item>
+ </taglist>
+</section>
<funcs>
<func>
<name>close(ConnectionRef) -> ok </name>
- <fsummary>Closes an SSH connection</fsummary>
+ <fsummary>Closes an SSH connection.</fsummary>
<type>
<v>ConnectionRef = ssh_connection_ref()</v>
</type>
@@ -81,104 +127,172 @@
<name>connect(Host, Port, Options) -> </name>
<name>connect(Host, Port, Options, Timeout) -> {ok,
ssh_connection_ref()} | {error, Reason}</name>
- <fsummary>Connect to an ssh server.</fsummary>
+ <fsummary>Connects to an SSH server.</fsummary>
<type>
<v>Host = string()</v>
<v>Port = integer()</v>
- <d>The default is <c><![CDATA[22]]></c>, the assigned well known port
+ <d><c><![CDATA[22]]></c> is default, the assigned well-known port
number for SSH.</d>
<v>Options = [{Option, Value}]</v>
- <v>Timeout = infinity | integer(milliseconds)</v>
- <d>Negotiation timeout, for connection timeout use the option <c>{connect_timeout, timeout()}</c>.</d>
+ <v>Timeout = infinity | integer()</v>
+ <d>Negotiation time-out in milli-seconds. The default value is <c>infinity</c>.
+ For connection time-out, use option <c>{connect_timeout, timeout()}</c>.</d>
</type>
<desc>
<p>Connects to an SSH server. No channel is started. This is done
by calling
- <seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/[2, 4]</seealso>.</p>
- <p>Options are:</p>
+ <seealso marker="ssh_connection#session_channel/2">
+ ssh_connection:session_channel/[2, 4]</seealso>.</p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
- <item> IP version to use.</item>
+ <item>
+ <p>IP version to use.</p>
+ </item>
<tag><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
- <p>Sets the user directory i.e. the directory containing
- ssh configuration files for the user such as
+ <p>Sets the user directory, that is, the directory containing
+ <c>ssh</c> configuration files for the user, such as
<c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c> and
+ id_dsa]]></c>, and
<c><![CDATA[authorized_key]]></c>. Defaults to the
directory normally referred to as
- <c><![CDATA[~/.ssh]]></c> </p>
+ <c><![CDATA[~/.ssh]]></c>.</p>
</item>
<tag><c><![CDATA[{dsa_pass_phrase, string()}]]></c></tag>
<item>
- <p>If the user dsa key is protected by a passphrase it can be
+ <p>If the user DSA key is protected by a passphrase, it can be
supplied with this option.
</p>
</item>
<tag><c><![CDATA[{rsa_pass_phrase, string()}]]></c></tag>
<item>
- <p>If the user rsa key is protected by a passphrase it can be
+ <p>If the user RSA key is protected by a passphrase, it can be
supplied with this option.
</p>
</item>
<tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag>
<item>
- <p>When true hosts are added to the
+ <p>When <c>true</c>, hosts are added to the
file <c><![CDATA[known_hosts]]></c> without asking the user.
- Defaults to false.
+ Defaults to <c>false</c>.
</p>
</item>
<tag><c><![CDATA[{user_interaction, boolean()}]]></c></tag>
<item>
- <p>If false disables the client to connect to the server
- if any user interaction is needed such as accepting that
- the server will be added to the <c>known_hosts</c> file or
- supplying a password. Defaults to true.
+ <p>If <c>false</c>, disables the client to connect to the server
+ if any user interaction is needed, such as accepting
+ the server to be added to the <c>known_hosts</c> file, or
+ supplying a password. Defaults to <c>true</c>.
Even if user interaction is allowed it can be
- suppressed by other options such as silently_accept_hosts and
- password. Do note that it may not always be desirable to use
- those options from a security point of view.</p>
+ suppressed by other options, such as <c>silently_accept_hosts</c>
+ and <c>password</c>. However, those optins are not always desirable
+ to use from a security point of view.</p>
+ </item>
+
+ <tag><c><![CDATA[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging when a server disconnects the client.</p>
+ </item>
+
+ <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
+ If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
+ report is generated.</p>
+ <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
+
<tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag>
<item>
+ <note>
+ <p>This option will be removed in OTP 20, but is kept for compatibility. It is ignored if
+ the preferred <c>pref_public_key_algs</c> option is used.</p>
+ </note>
<p>Sets the preferred public key algorithm to use for user
- authentication. If the the preferred algorithm fails for
- some reason, the other algorithm is tried. The default is
- to try <c><![CDATA['ssh-rsa']]></c> first.</p>
+ authentication. If the preferred algorithm fails,
+ the other algorithm is tried. If <c>{public_key_alg, 'ssh-rsa'}</c> is set, it is translated
+ to <c>{pref_public_key_algs, ['ssh-rsa','ssh-dss']}</c>. If it is
+ <c>{public_key_alg, 'ssh-dss'}</c>, it is translated
+ to <c>{pref_public_key_algs, ['ssh-dss','ssh-rsa']}</c>.
+ </p>
</item>
+
<tag><c><![CDATA[{pref_public_key_algs, list()}]]></c></tag>
<item>
- <p>List of public key algorithms to try to use, 'ssh-rsa' and 'ssh-dss' available.
- Will override <c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></p>
+ <p>List of user (client) public key algorithms to try to use.</p>
+ <p>The default value is
+ <c><![CDATA[['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521'] ]]></c>
+ </p>
+ <p>If there is no public key of a specified type available, the corresponding entry is ignored.</p>
+ </item>
+
+ <tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
+ <item>
+ <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
+ be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ </p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
+ <p>Here is an example of this option:</p>
+ <code>
+{preferred_algorithms,
+ [{public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr']},
+ {server2client,['aes128-cbc','3des-cbc']}]},
+ {mac,['hmac-sha2-256','hmac-sha1']},
+ {compression,[none,zlib]}
+}
+</code>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
+
+ <warning>
+ <p>Changing the values can make a connection less secure. Do not change unless you
+ know exactly what you are doing. If you do not understand the values then you
+ are not supposed to change them.</p>
+ </warning>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),I=integer(),Max=integer()}}]]></c></tag>
+ <item>
+ <p>Sets the three diffie-hellman-group-exchange parameters that guides the connected server in choosing a group.
+ See RFC 4419 for the function of thoose. The default value is <c>{1024, 6144, 8192}</c>.
+ </p>
</item>
+
<tag><c><![CDATA[{connect_timeout, timeout()}]]></c></tag>
<item>
- <p>Sets a timeout on the transport layer
- connection. Defaults to <c>infinity</c>.</p>
+ <p>Sets a time-out on the transport layer
+ connection. For <c>gen_tcp</c> the time is in milli-seconds and the default value is
+ <c>infinity</c>.</p>
</item>
<tag><c><![CDATA[{user, string()}]]></c></tag>
<item>
- <p>Provides a user name. If this option is not given, ssh
+ <p>Provides a username. If this option is not given, <c>ssh</c>
reads from the environment (<c><![CDATA[LOGNAME]]></c> or
- <c><![CDATA[USER]]></c> on unix,
+ <c><![CDATA[USER]]></c> on UNIX,
<c><![CDATA[USERNAME]]></c> on Windows).</p>
</item>
<tag><c><![CDATA[{password, string()}]]></c></tag>
<item>
- <p>Provide a password for password authentication. If
- this option is not given, the user will be asked for a
- password if the password authentication method is
+ <p>Provides a password for password authentication.
+ If this option is not given, the user is asked for a
+ password, if the password authentication method is
attempted.</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_client_key_api">ssh_client_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
</p>
</item>
<tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag>
<item>
- <p>If true, the client will not print out anything on authorization.</p>
+ <p>If <c>true</c>, the client does not print anything on authorization.</p>
</item>
<tag><c><![CDATA[{id_string, random | string()}]]></c></tag>
@@ -191,17 +305,17 @@
<tag><c><![CDATA[{fd, file_descriptor()}]]></c></tag>
<item>
- <p>Allow an existing file descriptor to be used
- (simply passed on to the transport protocol).</p></item>
+ <p>Allows an existing file descriptor to be used
+ (by passing it on to the transport protocol).</p></item>
<tag><c><![CDATA[{rekey_limit, integer()}]]></c></tag>
<item>
- <p>Provide, in bytes, when rekeying should be initiated,
- defaults to one time each GB and one time per hour.</p>
+ <p>Provides, in bytes, when rekeying is to be initiated.
+ Defaults to once per each GB and once per hour.</p>
</item>
<tag><c><![CDATA[{idle_time, integer()}]]></c></tag>
<item>
- <p>Sets a timeout on connection when no channels are active, default is infinity</p></item>
-
+ <p>Sets a time-out on a connection when no channels are active.
+ Defaults to <c>infinity</c>.</p></item>
<tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
<item>
<p>Provide a fun to implement your own logging of the SSH message SSH_MSG_DEBUG. The last three parameters are from the message, see RFC4253, section 11.3. The <c>ConnectionRef</c> is the reference to the connection on which the message arrived. The return value from the fun is not checked.</p>
@@ -215,18 +329,17 @@
<func>
<name>connection_info(ConnectionRef, [Option]) ->[{Option,
- Value}] </name>
- <fsummary> Retrieves information about a connection. </fsummary>
+ Value}]</name>
+ <fsummary>Retrieves information about a connection.</fsummary>
<type>
<v>Option = client_version | server_version | user | peer | sockname </v>
<v>Value = [option_value()] </v>
- <v>option_value() = {{Major::integer(), Minor::integer()}, VersionString::string()} | User::string() |
- Peer::{inet:hostname(), {inet::ip_adress(), inet::port_number()}} |
- Sockname::{inet::ip_adress(), inet::port_number()} () </v>
+ <v>option_value() = {{Major::integer(), Minor::integer()}, VersionString::string()} |
+ User::string() | Peer::{inet:hostname(), {inet::ip_adress(), inet::port_number()}} |
+ Sockname::{inet::ip_adress(), inet::port_number()}</v>
</type>
<desc>
- <p> Retrieves information about a connection.
- </p>
+ <p>Retrieves information about a connection.</p>
</desc>
</func>
@@ -247,111 +360,248 @@
<desc>
<p>Starts a server listening for SSH connections on the given
port.</p>
- <p>Options are:</p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
- <item> IP version to use when the host address is specified as <c>any</c>. </item>
+ <item><p>IP version to use when the host address is specified as <c>any</c>.</p></item>
<tag><c><![CDATA[{subsystems, [subsystem_spec()]}]]></c></tag>
<item>
- Provides specifications for handling of subsystems. The
- "sftp" subsystem spec can be retrieved by calling
- ssh_sftpd:subsystem_spec/1. If the subsystems option is
- not present the value of
- <c>[ssh_sftpd:subsystem_spec([])]</c> will be used. It is
- of course possible to set the option to the empty list if
- you do not want the daemon to run any subsystems at all.
+ <p>Provides specifications for handling of subsystems. The
+ "sftp" subsystem specification is retrieved by calling
+ <c>ssh_sftpd:subsystem_spec/1</c>. If the subsystems option is
+ not present, the value of
+ <c>[ssh_sftpd:subsystem_spec([])]</c> is used.
+ The option can be set to the empty list if
+ you do not want the daemon to run any subsystems.</p>
</item>
<tag><c><![CDATA[{shell, {Module, Function, Args} |
fun(string() = User) - > pid() | fun(string() = User,
ip_address() = PeerAddr) -> pid()}]]></c></tag>
<item>
- Defines the read-eval-print loop used when a shell is
- requested by the client. Default is to use the erlang shell:
- <c><![CDATA[{shell, start, []}]]></c>
+ <p>Defines the read-eval-print loop used when a shell is
+ requested by the client. The default is to use the Erlang shell:
+ <c><![CDATA[{shell, start, []}]]></c></p>
</item>
<tag><c><![CDATA[{ssh_cli, {channel_callback(),
channel_init_args()} | no_cli}]]></c></tag>
<item>
- Provides your own CLI implementation, i.e. a channel callback
- module that implements a shell and command execution. Note
- that you may customize the shell read-eval-print loop using the
- option <c>shell</c> which is much less work than implementing
- your own CLI channel. If set to <c>no_cli</c> you will disable
- CLI channels and only subsystem channels will be allowed.
+ <p>Provides your own CLI implementation, that is, a channel callback
+ module that implements a shell and command execution. The shell
+ read-eval-print loop can be customized, using the
+ option <c>shell</c>. This means less work than implementing
+ an own CLI channel. If set to <c>no_cli</c>, the CLI channels
+ are disabled and only subsystem channels are allowed.</p>
</item>
- <tag><c><![CDATA[{user_dir, String}]]></c></tag>
+ <tag><c><![CDATA[{user_dir, string()}]]></c></tag>
<item>
- <p>Sets the user directory i.e. the directory containing
- ssh configuration files for the user such as
+ <p>Sets the user directory. That is, the directory containing
+ <c>ssh</c> configuration files for the user, such as
<c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c> and
+ id_dsa]]></c>, and
<c><![CDATA[authorized_key]]></c>. Defaults to the
directory normally referred to as
- <c><![CDATA[~/.ssh]]></c> </p>
+ <c><![CDATA[~/.ssh]]></c>.</p>
</item>
<tag><c><![CDATA[{system_dir, string()}]]></c></tag>
<item>
<p>Sets the system directory, containing the host key files
- that identifies the host keys for ssh. The default is
- <c><![CDATA[/etc/ssh]]></c>, note that for security reasons
- this directory is normally only accessible by the root user.</p>
+ that identify the host keys for <c>ssh</c>. Defaults to
+ <c><![CDATA[/etc/ssh]]></c>. For security reasons,
+ this directory is normally accessible only to the root user.</p>
</item>
+
<tag><c><![CDATA[{auth_methods, string()}]]></c></tag>
<item>
- <p>Comma separated string that determines which
- authentication methodes that the server should support and
- in what order they will be tried. Defaults to
+ <p>Comma-separated string that determines which
+ authentication methods that the server is to support and
+ in what order they are tried. Defaults to
<c><![CDATA["publickey,keyboard-interactive,password"]]></c></p>
</item>
+
+ <tag><c><![CDATA[{auth_method_kb_interactive_data, PromptTexts}]]></c>
+ <br/><c>where:</c>
+ <br/><c>PromptTexts = kb_int_tuple() | fun(Peer::{IP::tuple(),Port::integer()}, User::string(), Service::string()) -> kb_int_tuple()</c>
+ <br/><c>kb_int_tuple() = {Name::string(), Instruction::string(), Prompt::string(), Echo::boolean()}</c>
+ </tag>
+ <item>
+ <p>Sets the text strings that the daemon sends to the client for presentation to the user when using <c>keyboar-interactive</c> authentication. If the fun/3 is used, it is called when the actual authentication occurs and may therefore return dynamic data like time, remote ip etc.</p>
+ <p>The parameter <c>Echo</c> guides the client about need to hide the password.</p>
+ <p>The default value is:
+ <c>{auth_method_kb_interactive_data, {"SSH server", "Enter password for \""++User++"\"", "password: ", false}></c></p>
+ </item>
+
<tag><c><![CDATA[{user_passwords, [{string() = User,
string() = Password}]}]]></c></tag>
<item>
- <p>Provide passwords for password authentication.They will
- be used when someone tries to connect to the server and
- public key user authentication fails. The option provides
- a list of valid user names and the corresponding password.
+ <p>Provides passwords for password authentication. The passwords
+ are used when someone tries to connect to the server and
+ public key user-authentication fails. The option provides
+ a list of valid usernames and the corresponding passwords.
</p>
</item>
<tag><c><![CDATA[{password, string()}]]></c></tag>
<item>
- <p>Provide a global password that will authenticate any
+ <p>Provides a global password that authenticates any
user. From a security perspective this option makes
the server very vulnerable.</p>
</item>
- <tag><c><![CDATA[{pwdfun, fun(User::string(), password::string()) -> boolean()}]]></c></tag>
+
+ <tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
+ <item>
+ <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
+ be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ </p>
+ <p>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
+ <p>Here is an example of this option:</p>
+ <code>
+{preferred_algorithms,
+ [{public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr']},
+ {server2client,['aes128-cbc','3des-cbc']}]},
+ {mac,['hmac-sha2-256','hmac-sha1']},
+ {compression,[none,zlib]}
+}
+</code>
+ <p>The example specifies different algorithms in the two directions (client2server and server2client),
+ for cipher but specifies the same algorithms for mac and compression in both directions.
+ The kex (key exchange) is implicit but public_key is set explicitly.</p>
+
+ <warning>
+ <p>Changing the values can make a connection less secure. Do not change unless you
+ know exactly what you are doing. If you do not understand the values then you
+ are not supposed to change them.</p>
+ </warning>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} {ssh_moduli_file,filename()} }]]></c></tag>
+ <item>
+ <p>Defines the groups the server may choose among when diffie-hellman-group-exchange is negotiated.
+ See RFC 4419 for details. The three variants of this option are:
+ </p>
+ <taglist>
+ <tag><c>{Size=integer(),G=integer(),P=integer()}</c></tag>
+ <item>The groups are given explicitly in this list. There may be several elements with the same <c>Size</c>.
+ In such a case, the server will choose one randomly in the negotiated Size.
+ </item>
+ <tag><c>{file,filename()}</c></tag>
+ <item>The file must have one or more three-tuples <c>{Size=integer(),G=integer(),P=integer()}</c>
+ terminated by a dot. The file is read when the daemon starts.
+ </item>
+ <tag><c>{ssh_moduli_file,filename()}</c></tag>
+ <item>The file must be in
+ <seealso marker="public_key:public_key#dh_gex_group/4">ssh-keygen moduli file format</seealso>.
+ The file is read when the daemon starts.
+ </item>
+ </taglist>
+ <p>The default list is fetched from the
+ <seealso marker="public_key:public_key#dh_gex_group/4">public_key</seealso> application.
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),Max=integer()}}]]></c></tag>
+ <item>
+ <p>Limits what a client can ask for in diffie-hellman-group-exchange.
+ The limits will be
+ <c>{MaxUsed = min(MaxClient,Max), MinUsed = max(MinClient,Min)}</c> where <c>MaxClient</c> and
+ <c>MinClient</c> are the values proposed by a connecting client.
+ </p>
+ <p>The default value is <c>{0,infinity}</c>.
+ </p>
+ <p>If <c>MaxUsed &lt; MinUsed</c> in a key exchange, it will fail with a disconnect.
+ </p>
+ <p>See RFC 4419 for the function of the Max and Min values.</p>
+ </item>
+
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string(), PeerAddress::{ip_adress(),port_number()}, State::any()) -> boolean() | disconnect | {boolean(),any()} }]]></c></tag>
+ <item>
+ <p>Provides a function for password validation. This could used for calling an external system or if
+ passwords should be stored as a hash. The fun returns:
+ </p>
+ <list type="bulleted">
+ <item><c>true</c> if the user and password is valid and</item>
+ <item><c>false</c> otherwise.</item>
+ </list>
+ <p>This fun can also be used to make delays in authentication tries for example by calling
+ <seealso marker="stdlib:timer#sleep/1">timer:sleep/1</seealso>. To facilitate counting of failed tries
+ the <c>State</c> variable could be used. This state is per connection only. The first time the pwdfun
+ is called for a connection, the <c>State</c> variable has the value <c>undefined</c>.
+ The pwdfun can return - in addition to the values above - a new state
+ as:
+ </p>
+ <list type="bulleted">
+ <item><c>{true, NewState:any()}</c> if the user and password is valid or</item>
+ <item><c>{false, NewState:any()}</c> if the user or password is invalid</item>
+ </list>
+ <p>A third usage is to block login attempts from a missbehaving peer. The <c>State</c> described above
+ can be used for this. In addition to the responses above, the following return value is introduced:
+ </p>
+ <list type="bulleted">
+ <item><c>disconnect</c> if the connection should be closed immediately after sending a SSH_MSG_DISCONNECT
+ message.</item>
+ </list>
+ </item>
+
+ <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string()) -> boolean()}]]></c></tag>
<item>
- <p>Provide a function for password validation. This is called
- with user and password as strings, and should return
+ <p>Provides a function for password validation. This function is called
+ with user and password as strings, and returns
<c><![CDATA[true]]></c> if the password is valid and
<c><![CDATA[false]]></c> otherwise.</p>
+ <p>This option (<c>{pwdfun,fun/2}</c>) is the same as a subset of the previous
+ (<c>{pwdfun,fun/4}</c>). It is kept for compatibility.</p>
</item>
<tag><c><![CDATA[{negotiation_timeout, integer()}]]></c></tag>
<item>
- <p>Max time in milliseconds for the authentication negotiation. The default value is 2 minutes. If the client fails to login within this time, the connection is closed.
+ <p>Maximum time in milliseconds for the authentication negotiation.
+ Defaults to 120000 (2 minutes). If the client fails to log in within this time,
+ the connection is closed.
</p>
</item>
<tag><c><![CDATA[{max_sessions, pos_integer()}]]></c></tag>
<item>
- <p>The maximum number of simultaneous sessions that are accepted at any time for this daemon. This includes sessions that are being authorized. So if set to <c>N</c>, and <c>N</c> clients have connected but not started the login process, the <c>N+1</c> connection attempt will be aborted. If <c>N</c> connections are authenticated and still logged in, no more loggins will be accepted until one of the existing ones log out.
+ <p>The maximum number of simultaneous sessions that are accepted at any time
+ for this daemon. This includes sessions that are being authorized.
+ Thus, if set to <c>N</c>, and <c>N</c> clients have connected but not started
+ the login process, connection attempt <c>N+1</c> is aborted.
+ If <c>N</c> connections are authenticated and still logged in, no more logins
+ are accepted until one of the existing ones log out.
</p>
- <p>The counter is per listening port, so if two daemons are started, one with <c>{max_sessions,N}</c> and the other with <c>{max_sessions,M}</c> there will be in total <c>N+M</c> connections accepted for the whole ssh application.
+ <p>The counter is per listening port. Thus, if two daemons are started, one with
+ <c>{max_sessions,N}</c> and the other with <c>{max_sessions,M}</c>, in total
+ <c>N+M</c> connections are accepted for the whole <c>ssh</c> application.
</p>
- <p>Note that if <c>parallel_login</c> is <c>false</c>, only one client at a time may be in the authentication phase.
+ <p>Notice that if <c>parallel_login</c> is <c>false</c>, only one client
+ at a time can be in the authentication phase.
</p>
- <p>As default, the option is not set. This means that the number is not limited.
+ <p>By default, this option is not set. This means that the number is not limited.
+ </p>
+ </item>
+
+ <tag><c><![CDATA[{max_channels, pos_integer()}]]></c></tag>
+ <item>
+ <p>The maximum number of channels with active remote subsystem that are accepted for
+ each connection to this daemon</p>
+ <p>By default, this option is not set. This means that the number is not limited.
</p>
</item>
+
<tag><c><![CDATA[{parallel_login, boolean()}]]></c></tag>
<item>
- <p>If set to false (the default value), only one login is handled a time. If set to true, an unlimited number of login attempts will be allowed simultanously.
+ <p>If set to false (the default value), only one login is handled at a time.
+ If set to true, an unlimited number of login attempts are allowed simultaneously.
</p>
- <p>If the <c>max_sessions</c> option is set to <c>N</c> and <c>parallel_login</c> is set to <c>true</c>, the max number of simultaneous login attempts at any time is limited to <c>N-K</c> where <c>K</c> is the number of authenticated connections present at this daemon.
+ <p>If the <c>max_sessions</c> option is set to <c>N</c> and <c>parallel_login</c>
+ is set to <c>true</c>, the maximum number of simultaneous login attempts at any time is
+ limited to <c>N-K</c>, where <c>K</c> is the number of authenticated connections present
+ at this daemon.
</p>
<warning>
- <p>Do not enable <c>parallel_logins</c> without protecting the server by other means, for example the <c>max_sessions</c> option or a firewall configuration. If set to <c>true</c>, there is no protection against DOS attacks.</p>
+ <p>Do not enable <c>parallel_logins</c> without protecting the server by other means,
+ for example, by the <c>max_sessions</c> option or a firewall configuration. If set to
+ <c>true</c>, there is no protection against DOS attacks.</p>
</warning>
</item>
@@ -369,27 +619,53 @@
</p>
</item>
- <tag><c><![CDATA[{key_cb, atom()}]]></c></tag>
+ <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
<item>
- <p>Module implementing the behaviour <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
- Can be used to customize the handling of public keys.
+ <p>Module implementing the behaviour <seealso
+ marker="ssh_server_key_api">ssh_server_key_api</seealso>. Can be used to
+ customize the handling of public keys. If callback options are provided
+ along with the module name, they are made available to the callback
+ module via the options passed to it under the key 'key_cb_private'.
+ </p>
+ </item>
+
+ <tag><c>{profile, atom()}</c></tag>
+ <item>
+ <p>Used together with <c>ip-address</c> and <c>port</c> to
+ uniquely identify a ssh daemon. This can be useful in a
+ virtualized environment, where there can be more that one
+ server that has the same <c>ip-address</c> and
+ <c>port</c>. If this property is not explicitly set, it is
+ assumed that the the <c>ip-address</c> and <c>port</c>
+ uniquely identifies the SSH daemon.
</p>
</item>
+
<tag><c><![CDATA[{fd, file_descriptor()}]]></c></tag>
<item>
- <p>Allow an existing file-descriptor to be used
- (simply passed on to the transport protocol).</p></item>
- <tag><c><![CDATA[{failfun, fun(User::string(), PeerAddress::ip_address(), Reason::term()) -> _}]]></c></tag>
+ <p>Allows an existing file-descriptor to be used
+ (passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{failfun, fun(User::string(),
+ PeerAddress::ip_address(), Reason::term()) -> _}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user fails to authenticate.</p>
+ <p>Provides a fun to implement your own logging when a user fails to authenticate.</p>
</item>
- <tag><c><![CDATA[{connectfun, fun(User::string(), PeerAddress::ip_address(), Method::string()) ->_}]]></c></tag>
+ <tag><c><![CDATA[{connectfun, fun(User::string(), PeerAddress::ip_address(),
+ Method::string()) ->_}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user authenticates to the server.</p>
+ <p>Provides a fun to implement your own logging when a user authenticates to the server.</p>
</item>
<tag><c><![CDATA[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
<item>
- <p>Provide a fun to implement your own logging when a user disconnects from the server.</p>
+ <p>Provides a fun to implement your own logging when a user disconnects from the server.</p>
+ </item>
+
+ <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
+ <item>
+ <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
+ If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
+ report is generated.</p>
+ <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
</item>
<tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
@@ -403,21 +679,41 @@
</desc>
</func>
+ <func>
+ <name>default_algorithms() -> algs_list()</name>
+ <fsummary>Get a list declaring the supported algorithms</fsummary>
+ <desc>
+ <p>Returns a key-value list, where the keys are the different types of algorithms and the values are the
+ algorithms themselves. An example:</p>
+ <code>
+20> ssh:default_algorithms().
+[{kex,['diffie-hellman-group1-sha1']},
+ {public_key,['ssh-rsa','ssh-dss']},
+ {cipher,[{client2server,['aes128-ctr','aes128-cbc','3des-cbc']},
+ {server2client,['aes128-ctr','aes128-cbc','3des-cbc']}]},
+ {mac,[{client2server,['hmac-sha2-256','hmac-sha1']},
+ {server2client,['hmac-sha2-256','hmac-sha1']}]},
+ {compression,[{client2server,[none,zlib]},
+ {server2client,[none,zlib]}]}]
+21>
+</code>
+ </desc>
+ </func>
<func>
<name>shell(Host) -> </name>
<name>shell(Host, Option) -> </name>
<name>shell(Host, Port, Option) -> _</name>
- <fsummary> </fsummary>
+ <fsummary>Starts an interactive shell over an SSH server.</fsummary>
<type>
- <v> Host = string()</v>
- <v> Port = integer()</v>
- <v> Options - see ssh:connect/3</v>
+ <v>Host = string()</v>
+ <v>Port = integer()</v>
+ <v>Options - see ssh:connect/3</v>
</type>
<desc>
- <p>Starts an interactive shell via an SSH server on the
+ <p>Starts an interactive shell over an SSH server on the
given <c>Host</c>. The function waits for user input,
- and will not return until the remote shell is ended (i.e.
+ and does not return until the remote shell is ended (that is,
exit from the shell).
</p>
</desc>
@@ -426,28 +722,29 @@
<func>
<name>start() -> </name>
<name>start(Type) -> ok | {error, Reason}</name>
- <fsummary>Starts the SSH application. </fsummary>
+ <fsummary>Starts the SSH application.</fsummary>
<type>
<v>Type = permanent | transient | temporary</v>
<v>Reason = term() </v>
</type>
<desc>
- <p>Utility function that starts crypto, public_key and the SSH
- application. Defult type is temporary.
- See also <seealso marker="kernel:application">application(3)</seealso>
- </p>
+ <p>Utility function that starts the applications <c>crypto</c>, <c>public_key</c>,
+ and <c>ssh</c>. Default type is <c>temporary</c>.
+ For more information, see the <seealso marker="kernel:application">application(3)</seealso>
+ manual page in <c>kernel</c>.</p>
</desc>
</func>
<func>
<name>stop() -> ok | {error, Reason}</name>
- <fsummary>Stops the SSH application.</fsummary>
+ <fsummary>Stops the <c>ssh</c> application.</fsummary>
<type>
<v>Reason = term()</v>
</type>
<desc>
- <p>Stops the SSH application. See also
- <seealso marker="kernel:application">application(3)</seealso></p>
+ <p>Stops the <c>ssh</c> application.
+ For more information, see the <seealso marker="kernel:application">application(3)</seealso>
+ manual page in <c>kernel</c>.</p>
</desc>
</func>
@@ -471,7 +768,7 @@
<name>stop_listener(DaemonRef) -> </name>
<name>stop_listener(Address, Port) -> ok </name>
<fsummary>Stops the listener, but leaves existing connections started
- by the listener up and running.</fsummary>
+ by the listener operational.</fsummary>
<type>
<v>DaemonRef = ssh_daemon_ref()</v>
<v>Address = ip_address()</v>
@@ -479,7 +776,7 @@
</type>
<desc>
<p>Stops the listener, but leaves existing connections started
- by the listener up and running.</p>
+ by the listener operational.</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_app.xml b/lib/ssh/doc/src/ssh_app.xml
index a1d2402790..f6ce44c015 100644
--- a/lib/ssh/doc/src/ssh_app.xml
+++ b/lib/ssh/doc/src/ssh_app.xml
@@ -4,97 +4,316 @@
<appref>
<header>
<copyright>
- <year>2012</year><year>2013</year>
+ <year>2012</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>SSH</title>
+ <prepared></prepared>
+ <docno></docno>
+ <checked></checked>
+ <date></date>
+ <rev></rev>
<file>ssh_app.xml</file>
</header>
<app>SSH</app>
- <appsummary>The ssh application implements the SSH (Secure Shell) protocol and
- provides an SFTP (SSH File Transfer Protocol) client and server. </appsummary>
+ <appsummary>The ssh application implements the Secure Shell (SSH) protocol and
+ provides an SSH File Transfer Protocol (SFTP) client and server.</appsummary>
+ <description>
+ <p>The <c>ssh</c> application is an implementation of the SSH protocol in Erlang.
+ <c>ssh</c> offers API functions to write customized SSH clients and servers as well as
+ making the Erlang shell available over SSH. An SFTP client, <c>ssh_sftp</c>, and server,
+ <c>ssh_sftpd</c>, are also included.</p>
+ </description>
- <section>
+ <section>
<title>DEPENDENCIES</title>
- <p>The ssh application uses the Erlang applications public_key and
- crypto to handle public keys and encryption, hence these
- applications needs to be loaded for the ssh application to work. In
- an embedded environment that means they need to be started with
- application:start/[1,2] before the ssh application is started.
+ <p>The <c>ssh</c> application uses the applications
+ <seealso marker="public_key:public_key">public_key</seealso> and
+ <seealso marker="crypto:crypto">crypto</seealso>
+ to handle public keys and encryption. Hence, these
+ applications must be loaded for the <c>ssh</c> application to work. In
+ an embedded environment this means that they must be started with
+ <seealso marker="kernel:application#start/1">application:start/1,2</seealso> before the
+ <c>ssh</c> application is started.
</p>
</section>
- <section>
+ <section>
<title>CONFIGURATION</title>
- <p>The ssh application does not currently have an application
- specific configuration file as described in application(3),
- however it will by default use the following configuration files
- from openssh: known_hosts, authorized_keys, authorized_keys2,
- id_dsa and id_rsa, ssh_host_dsa_key and ssh_host_rsa_key. By
- default Erlang SSH will look for id_dsa, id_rsa, known_hosts
- and authorized_keys in ~/.ssh, and the host key files in /etc/ssh
- . These locations may be changed by the options user_dir and
- system_dir. Public key handling may also be customized by
- providing a callback module implementing the behaviors
- <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and
- <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
- </p>
+ <p>The <c>ssh</c> application does not have an application-
+ specific configuration file, as described in <seealso marker="kernel:application">application(3)</seealso>.
+ However, by default it use the following configuration files
+ from OpenSSH:</p>
+ <list type="bulleted">
+ <item><c>known_hosts</c></item>
+ <item><c>authorized_keys</c></item>
+ <item><c>authorized_keys2</c></item>
+ <item><c>id_dsa</c></item>
+ <item><c>id_rsa</c></item>
+ <item><c>id_ecdsa</c></item>
+ <item><c>ssh_host_dsa_key</c></item>
+ <item><c>ssh_host_rsa_key</c></item>
+ <item><c>ssh_host_ecdsa_key</c></item>
+ </list>
+ <p>By default, <c>ssh</c> looks for <c>id_dsa</c>, <c>id_rsa</c>,
+ <c>id_ecdsa_key</c>,
+ <c>known_hosts</c>, and <c>authorized_keys</c> in ~/.ssh,
+ and for the host key files in <c>/etc/ssh</c>. These locations can be changed
+ by the options <c>user_dir</c> and <c>system_dir</c>.
+ </p>
+ <p>Public key handling can also be customized through a callback module that
+ implements the behaviors
+ <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and
+ <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>.
+ </p>
- <section>
- <title>PUBLIC KEYS</title>
- <p>
- id_dsa and id_rsa are the users private key files, note that
- the public key is part of the private key so the ssh
- application will not use the id_&lt;*>.pub files. These are
- for the users convenience when he/she needs to convey their
+ </section>
+ <section>
+ <title>Public Keys</title>
+ <p><c>id_dsa</c>, <c>id_rsa</c> and <c>id_ecdsa</c> are the users private key files.
+ Notice that the public key is part of the private key so the <c>ssh</c>
+ application does not use the <c>id_&lt;*>.pub</c> files. These are
+ for the user's convenience when it is needed to convey the user's
public key.
</p>
- </section>
-
- <section>
- <title>KNOW HOSTS</title>
- <p>The known_hosts file contains a list of approved servers and
- their public keys. Once a server is listed, it can be verified
+ </section>
+ <section>
+ <title>Known Hosts</title>
+ <p>The <c>known_hosts</c> file contains a list of approved servers and
+ their public keys. Once a server is listed, it can be verified
without user interaction.
</p>
- </section>
-
- <section>
- <title>AUTHORIZED KEYS</title>
- <p>The authorized key file keeps track of the user's authorized
+ </section>
+ <section>
+ <title>Authorized Keys</title>
+ <p>The <c>authorized_key</c> file keeps track of the user's authorized
public keys. The most common use of this file is to let users
- log in without entering their password which is supported by the
- Erlang SSH daemon.
+ log in without entering their password, which is supported by the
+ Erlang <c>ssh</c> daemon.
</p>
- </section>
-
- <section>
- <title>HOST KEYS</title>
- <p>Currently rsa and dsa host keys are supported and are
- expected to be found in files named ssh_host_rsa_key and
- ssh_host_dsa_key.
+ </section>
+ <section>
+ <title>Host Keys</title>
+ <p>RSA and DSA host keys are supported and are
+ expected to be found in files named <c>ssh_host_rsa_key</c>,
+ <c>ssh_host_dsa_key</c> and <c>ssh_host_ecdsa_key</c>.
</p>
- </section>
+ </section>
+ <section>
+ <title>ERROR LOGGER AND EVENT HANDLERS</title>
+ <p>The <c>ssh</c> application uses the default <seealso marker="kernel:error_logger">OTP error logger</seealso> to log unexpected errors or print information about special events.</p>
+ </section>
+
+ <section>
+ <marker id="supported"/>
+ <title>SUPPORTED SPECIFICATIONS AND STANDARDS</title>
+ <p>The supported SSH version is 2.0.</p>
+ </section>
+ <section>
+ <title>Algorithms</title>
+ <p>The actual set of algorithms may vary depending on which OpenSSL crypto library that is installed on the machine.
+ For the list on a particular installation, use the command
+ <seealso marker="ssh:ssh#default_algorithms/0">ssh:default_algorithms/0</seealso>.
+ The user may override the default algorithm configuration both on the server side and the client side.
+ See the option <c>preferred_algorithms</c> in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and
+ <seealso marker="ssh:ssh#connect/3">ssh:connect/3,4</seealso> functions.
+ </p>
+
+ <p>Supported algorithms are:</p>
+
+ <taglist>
+ <tag>Key exchange algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdh-sha2-nistp256</item>
+ <item>ecdh-sha2-nistp384</item>
+ <item>ecdh-sha2-nistp521</item>
+ <item>diffie-hellman-group-exchange-sha1</item>
+ <item>diffie-hellman-group-exchange-sha256</item>
+ <item>diffie-hellman-group14-sha1</item>
+ <item>diffie-hellman-group1-sha1</item>
+ </list>
+ </item>
+
+ <tag>Public key algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>ecdsa-sha2-nistp256</item>
+ <item>ecdsa-sha2-nistp384</item>
+ <item>ecdsa-sha2-nistp521</item>
+ <item>ssh-rsa</item>
+ <item>ssh-dss</item>
+ </list>
+ </item>
+
+ <tag>MAC algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>hmac-sha2-256</item>
+ <item>hmac-sha2-512</item>
+ <item>hmac-sha1</item>
+ </list>
+ </item>
+
+ <tag>Encryption algorithms (ciphers)</tag>
+ <item>
+ <list type="bulleted">
+ <item>[email protected] (AEAD_AES_128_GCM)</item>
+ <item>[email protected] (AEAD_AES_256_GCM)</item>
+ <item>aes128-ctr</item>
+ <item>aes192-ctr</item>
+ <item>aes256-ctr</item>
+ <item>aes128-cbc</item>
+ <item>3des-cbc</item>
+ </list>
+ <p>Following the internet de-facto standard, the cipher and mac algorithm AEAD_AES_128_GCM is selected when the
+ cipher [email protected] is negotiated. The cipher and mac algorithm AEAD_AES_256_GCM is selected when the
+ cipher [email protected] is negotiated.
+ </p>
+ <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
+ for more information.
+ </p>
+ </item>
+
+ <tag>Compression algorithms</tag>
+ <item>
+ <list type="bulleted">
+ <item>none</item>
+ <item>[email protected]</item>
+ <item>zlib</item>
+ </list>
+ </item>
+ </taglist>
+ </section>
+ <section>
+ <title>Unicode support</title>
+ <p>Unicode filenames are supported if the emulator and the underlaying OS support it. See section DESCRIPTION in the
+ <seealso marker="kernel:file">file</seealso> manual page in <c>kernel</c> for information about this subject.
+ </p>
+ <p>The shell and the cli both support unicode.
+ </p>
+ </section>
+
+ <section>
+ <title>Rfcs</title>
+ <p>The following rfc:s are supported:</p>
+ <list type="bulleted">
+ <item><url href="https://tools.ietf.org/html/rfc4251">RFC 4251</url>, The Secure Shell (SSH) Protocol Architecture.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>9.4.6 Host-Based Authentication</item>
+ <item>9.5.2 Proxy Forwarding</item>
+ <item>9.5.3 X11 Forwarding</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4252">RFC 4252</url>, The Secure Shell (SSH) Authentication Protocol.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>9. Host-Based Authentication: "hostbased"</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol.
+ <p></p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4254">RFC 4254</url>, The Secure Shell (SSH) Connection Protocol.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>6.3. X11 Forwarding</item>
+ <item>7. TCP/IP Port Forwarding</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4256">RFC 4256</url>, Generic Message Exchange Authentication for
+ the Secure Shell Protocol (SSH).
+ <p>Except</p>
+ <list type="bulleted">
+ <item><c>num-prompts > 1</c></item>
+ <item>password changing</item>
+ <item>other identification methods than userid-password</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url>, Diffie-Hellman Group Exchange for
+ the Secure Shell (SSH) Transport Layer Protocol.
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc4716">RFC 4716</url>, The Secure Shell (SSH) Public Key File Format.
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5647">RFC 5647</url>, AES Galois Counter Mode for
+ the Secure Shell Transport Layer Protocol.
+ <p><marker id="rfc5647_note"/>There is an ambiguity in the synchronized selection of cipher and mac algorithm.
+ This is resolved by OpenSSH in the ciphers [email protected] and [email protected] which are implemented.
+ If the explicit ciphers and macs AEAD_AES_128_GCM or AEAD_AES_256_GCM are needed,
+ they could be enabled with the option preferred_algorithms.
+ </p>
+ <warning>
+ <p>
+ If the client or the server is not Erlang/OTP, it is the users responsibility to check that
+ other implementation has the same interpretation of AEAD_AES_*_GCM as the Erlang/OTP SSH before
+ enabling them. The aes*[email protected] variants are always safe to use since they lack the
+ ambiguity.
+ </p>
+ </warning>
+ <p>The second paragraph in section 5.1 is resolved as:</p>
+ <list type="ordered">
+ <item>If the negotiated cipher is AEAD_AES_128_GCM, the mac algorithm is set to AEAD_AES_128_GCM.</item>
+ <item>If the negotiated cipher is AEAD_AES_256_GCM, the mac algorithm is set to AEAD_AES_256_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_128_GCM, the cipher is set to AEAD_AES_128_GCM.</item>
+ <item>If the mac algorithm is AEAD_AES_256_GCM, the cipher is set to AEAD_AES_256_GCM.</item>
+ </list>
+ <p>The first rule that matches when read in order from the top is applied</p>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc5656">RFC 5656</url>, Elliptic Curve Algorithm Integration in
+ the Secure Shell Transport Layer.
+ <p>Except</p>
+ <list type="bulleted">
+ <item>5. ECMQV Key Exchange</item>
+ <item>6.4. ECMQV Key Exchange and Verification Method Name</item>
+ <item>7.2. ECMQV Message Numbers</item>
+ <item>10.2. Recommended Curves</item>
+ </list>
+ <p/>
+ </item>
+
+ <item><url href="https://tools.ietf.org/html/rfc6668">RFC 6668</url>, SHA-2 Data Integrity Verification for
+ the Secure Shell (SSH) Transport Layer Protocol
+ <p>Comment: Defines hmac-sha2-256 and hmac-sha2-512
+ </p>
+ </item>
+
+ </list>
+
</section>
<section>
<title>SEE ALSO</title>
- <p>application(3)</p>
+ <p><seealso marker="kernel:application">application(3)</seealso></p>
</section>
</appref>
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_channel.xml
index a52a6a115e..abfe590647 100644
--- a/lib/ssh/doc/src/ssh_channel.xml
+++ b/lib/ssh/doc/src/ssh_channel.xml
@@ -9,83 +9,99 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_channel</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_channel</module>
<modulesummary>-behaviour(ssh_channel).
</modulesummary>
<description>
<p>SSH services (clients and servers) are implemented as channels
- that are multiplexed over an SSH connection and communicates via
+ that are multiplexed over an SSH connection and communicates over
the <url href="http://www.ietf.org/rfc/rfc4254.txt"> SSH
Connection Protocol</url>. This module provides a callback API
- that takes care of generic channel aspects such as flow control
- and close messages and lets the callback functions take care of
+ that takes care of generic channel aspects, such as flow control
+ and close messages. It lets the callback functions take care of
the service (application) specific parts. This behavior also ensures
that the channel process honors the principal of an OTP-process so
that it can be part of a supervisor tree. This is a requirement of
channel processes implementing a subsystem that will be added to
- the SSH applications supervisor tree.
+ the <c>ssh</c> applications supervisor tree.
</p>
- <note> <p>When implementing a SSH subsystem use the
- <c>-behaviour(ssh_daemon_channel).</c> instead of <c>-behaviour(ssh_channel).</c>
- as the only relevant callback functions for subsystems are
- init/1, handle_ssh_msg/2, handle_msg/2 and terminate/2, so the ssh_daemon_channel
- behaviour is limited version of the ssh_channel behaviour.
- </p> </note>
+ <note><p>When implementing an <c>ssh</c> subsystem, use
+ <c>-behaviour(ssh_daemon_channel)</c> instead of <c>-behaviour(ssh_channel)</c>.
+ The reason is that the only relevant callback functions for subsystems are
+ <c>init/1</c>, <c>handle_ssh_msg/2</c>, <c>handle_msg/2</c>, and <c>terminate/2</c>.
+ So, the <c>ssh_daemon_channel</c> behaviour is a limited version of the
+ <c>ssh_channel</c> behaviour.
+ </p></note>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type:</p>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both:</p>
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = list of ASCII characters</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
- <p><c>ssh_connection_ref() - opaque to the user returned by
- ssh:connect/3 or sent to an SSH channel process</c></p>
- <p><c>ssh_channel_id() = integer() </c></p>
- <p><c>ssh_data_type_code() = 1 ("stderr") | 0 ("normal") are
- currently valid values see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 5.2.</c></p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p>list of ASCII characters</p></item>
+ <tag><c>timeout() =</c></tag>
+ <item><p><c>infinity | integer()</c> in milliseconds</p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() -as returned by
+ <c>ssh:connect/3</c> or sent to an SSH channel process</p></item>
+ <tag><c>ssh_channel_id() =</c></tag>
+ <item><p><c>integer()</c></p></item>
+ <tag><c>ssh_data_type_code() =</c></tag>
+ <item><p><c>1</c> ("stderr") | <c>0</c> ("normal") are
+ the valid values,
+ see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
+ Section 5.2</p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>call(ChannelRef, Msg) -></name>
<name>call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason}</name>
- <fsummary> Makes a synchronous call to a channel.</fsummary>
+ <fsummary>Makes a synchronous call to a channel.</fsummary>
<type>
<v>ChannelRef = pid() </v>
- <d>As returned by start_link/4 </d>
- <v>Msg = term() </v>
- <v>Timeout = timeout() </v>
- <v>Reply = term() </v>
- <v>Reason = closed | timeout </v>
+ <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <v>Msg = term()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reply = term()</v>
+ <v>Reason = closed | timeout</v>
</type>
<desc>
<p>Makes a synchronous call to the channel process by sending
- a message and waiting until a reply arrives or a timeout
- occurs. The channel will call <seealso marker =
+ a message and waiting until a reply arrives, or a time-out
+ occurs. The channel calls <seealso marker =
"#Module:handle_call-3">Module:handle_call/3</seealso>
- to handle the message. If the channel process does not exist
+ to handle the message. If the channel process does not exist,
<c>{error, closed}</c> is returned.
</p>
</desc>
@@ -96,14 +112,14 @@
<fsummary>Sends an asynchronous message to the channel
ChannelRef and returns ok.</fsummary>
<type>
- <v>ChannelRef = pid() </v>
- <d>As returned by start_link/4 </d>
- <v>Msg = term() </v>
+ <v>ChannelRef = pid()</v>
+ <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <v>Msg = term()</v>
</type>
<desc>
<p>Sends an asynchronous message to the channel process and
returns ok immediately, ignoring if the destination node or
- channel process does not exist. The channel will call
+ channel process does not exist. The channel calls
<seealso marker = "#Module:handle_cast-2">Module:handle_cast/2</seealso>
to handle the message.
</p>
@@ -112,31 +128,32 @@
<func>
<name>enter_loop(State) -> _ </name>
- <fsummary> Makes an existing process an ssh_channel process. </fsummary>
+ <fsummary>Makes an existing process an ssh_channel process.</fsummary>
<type>
- <v> State = term() - as returned by <seealso marker = "#init-1">ssh_channel:init/1</seealso></v>
+ <v>State = term()</v>
+ <d>as returned by <seealso marker = "#init-1">ssh_channel:init/1</seealso></d>
</type>
<desc>
- <p> Makes an existing process an <c>ssh_channel</c>
- process. Does not return, instead the calling process will
- enter the <c>ssh_channel</c> process receive loop and become an
- <c>ssh_channel process.</c> The process must have been started using
- one of the start functions in proc_lib, see <seealso
- marker="stdlib:proc_lib">proc_lib(3)</seealso>. The
- user is responsible for any initialization of the process
- and needs to call <seealso marker = "#init-1">ssh_channel:init/1</seealso>
+ <p>Makes an existing process an <c>ssh_channel</c>
+ process. Does not return, instead the calling process
+ enters the <c>ssh_channel</c> process receive loop and become an
+ <c>ssh_channel process</c>. The process must have been started using
+ one of the start functions in <c>proc_lib</c>, see the <seealso
+ marker="stdlib:proc_lib">proc_lib(3)</seealso> manual page in <c>stdlib</c>.
+ The user is responsible for any initialization of the process
+ and must call <seealso marker = "#init-1">ssh_channel:init/1</seealso>.
</p>
</desc>
</func>
<func>
<name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name>
- <fsummary> Initiates a ssh_channel process.</fsummary>
+ <fsummary>Initiates an <c>ssh_channel</c> process.</fsummary>
<type>
<v>Options = [{Option, Value}]</v>
<v>State = term()</v>
- <v>Timeout = timeout() </v>
- <v>Reason = term() </v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
<p>
@@ -144,48 +161,47 @@
</p>
<taglist>
<tag><c><![CDATA[{channel_cb, atom()}]]></c></tag>
- <item>The module that implements the channel behaviour.</item>
+ <item><p>The module that implements the channel behaviour.</p></item>
<tag><c><![CDATA[{init_args(), list()}]]></c></tag>
- <item> The list of arguments to the callback module's
- init function.</item>
+ <item><p>The list of arguments to the <c>init</c> function of the callback module.</p></item>
<tag><c><![CDATA[{cm, connection_ref()}]]></c></tag>
- <item> Reference to the ssh connection as returned by <seealso
- marker="ssh#connect-3">ssh:connect/3</seealso></item>
+ <item><p>Reference to the <c>ssh</c> connection as returned by <seealso
+ marker="ssh#connect-3">ssh:connect/3</seealso></p></item>
<tag><c><![CDATA[{channel_id, channel_id()}]]></c></tag>
- <item> Id of the SSH channel.</item>
+ <item><p>Id of the <c>ssh</c> channel.</p></item>
</taglist>
<note><p>This function is normally not called by the
- user. The user only needs to call if for some reason the
+ user. The user only needs to call if the
channel process needs to be started with help of
<c>proc_lib</c> instead of calling
<c>ssh_channel:start/4</c> or
- <c>ssh_channel:start_link/4</c> </p>
+ <c>ssh_channel:start_link/4</c>.</p>
</note>
</desc>
</func>
<func>
<name>reply(Client, Reply) -> _</name>
- <fsummary>Send a reply to a client.</fsummary>
+ <fsummary>Sends a reply to a client.</fsummary>
<type>
- <v>Client - opaque to the user, see explanation below</v>
+ <v>Client = opaque()</v>
<v>Reply = term()</v>
</type>
<desc>
- <p>This function can be used by a channel to explicitly send a
+ <p>This function can be used by a channel to send a
reply to a client that called <c>call/[2,3]</c> when the reply
cannot be defined in the return value of
<seealso marker ="#Module:handle_call-3">Module:handle_call/3</seealso>.</p>
<p><c>Client</c> must be the <c>From</c> argument provided to
the callback function <c>handle_call/3</c>.
<c>Reply</c> is an arbitrary term,
- which will be given back to the client as the return value of
- <seealso marker="#call-2">ssh_channel:call/[2,3].</seealso>></p>
+ which is given back to the client as the return value of
+ <seealso marker="#call-2">ssh_channel:call/[2,3].</seealso></p>
</desc>
</func>
@@ -193,24 +209,25 @@
<name>start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name>
<name>start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) ->
{ok, ChannelRef} | {error, Reason}</name>
- <fsummary> Starts a processes that handles a SSH channel. </fsummary>
+ <fsummary>Starts a process that handles an SSH channel.</fsummary>
<type>
<v>SshConnection = ssh_connection_ref()</v>
- <v>ChannelId = ssh_channel_id() </v>
- <d> As returned by cannot be defined in the return value of
- <seealso marker ="ssh_connection#session_channel/2">ssh_connection:session_channel/[2,4]</seealso></d>
+ <v>ChannelId = ssh_channel_id()</v>
+ <d>As returned by
+ <seealso marker ="ssh_connection#session_channel/2">
+ ssh_connection:session_channel/[2,4]</seealso>.</d>
<v>ChannelCb = atom()</v>
- <d> The name of the module implementing the service specific parts
+ <d>Name of the module implementing the service-specific parts
of the channel.</d>
<v>CbInitArgs = [term()]</v>
- <d>Argument list for the init function in the callback module. </d>
+ <d>Argument list for the <c>init</c> function in the callback module.</d>
<v>ChannelRef = pid()</v>
</type>
<desc>
- <p>Starts a processes that handles an SSH channel. It will be
- called internally by the SSH daemon or explicitly by the SSH
- client implementations. The behavior will set the
- <c>trap_exit</c> flag to true.
+ <p>Starts a process that handles an SSH channel. It is
+ called internally, by the <c>ssh</c> daemon, or explicitly by the <c>ssh</c>
+ client implementations. The behavior sets the
+ <c>trap_exit</c> flag to <c>true</c>.
</p>
</desc>
</func>
@@ -219,19 +236,19 @@
<section>
<marker id="cb_timeouts"></marker>
- <title> CALLBACK TIMEOUTS</title>
+ <title>CALLBACK TIME-OUTS</title>
- <p>The timeout values that may be returned by the callback functions
- has the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>
- If the timeout occurs <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
- will be called as <c>handle_msg(timeout, State). </c></p>
+ <p>The time-out values that can be returned by the callback functions
+ have the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>.
+ If the time-out occurs, <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
+ is called as <c>handle_msg(timeout, State)</c>.</p>
</section>
<funcs>
<func>
<name>Module:code_change(OldVsn, State, Extra) -> {ok,
NewState}</name>
- <fsummary> Converts process state when code is changed.</fsummary>
+ <fsummary>Converts process state when code is changed.</fsummary>
<type>
<v>OldVsn = term()</v>
<d>In the case of an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and
@@ -241,31 +258,31 @@
<c>Module</c>. If no such attribute is defined, the version is
the checksum of the BEAM file.</d>
<v>State = term()</v>
- <d>The internal state of the channel.</d>
+ <d>Internal state of the channel.</d>
<v>Extra = term()</v>
- <d>Passed as-is from the <c>{advanced,Extra}</c>
+ <d>Passed "as-is" from the <c>{advanced,Extra}</c>
part of the update instruction.</d>
</type>
<desc>
- <p> Converts process state when code is changed.</p>
+ <p>Converts process state when code is changed.</p>
- <p>This function is called by a client side channel when it
- should update its internal state during a release
- upgrade/downgrade, i.e. when the instruction
- <c>{update,Module,Change,...}</c> where
- <c>Change={advanced,Extra}</c> is given in the <c>appup</c>
- file. See <seealso marker="doc/design_principles:release_handling#instr">OTP
- Design Principles</seealso> for more information.
+ <p>This function is called by a client-side channel when it
+ is to update its internal state during a release
+ upgrade or downgrade, that is, when the instruction
+ <c>{update,Module,Change,...}</c>, where
+ <c>Change={advanced,Extra}</c>, is given in the <c>appup</c>
+ file. For more information, refer to Section 9.11.6
+ Release Handling Instructions in the
+ <seealso marker="doc/design_principles:release_handling#instr">System Documentation</seealso>.
</p>
<note><p>Soft upgrade according to the OTP release concept
is not straight forward for the server side, as subsystem
- channel processes are spawned by the SSH application and
- hence added to its supervisor tree. It could be possible to
- upgrade the subsystem channels, when upgrading the user
- application, if the callback functions can handle two
- versions of the state, but this function can not be used in
- the normal way.</p>
+ channel processes are spawned by the <c>ssh</c> application and
+ hence added to its supervisor tree. The subsystem channels can
+ be upgraded when upgrading the user application, if the callback
+ functions can handle two versions of the state, but this function
+ cannot be used in the normal way.</p>
</note>
</desc>
@@ -274,36 +291,38 @@
<func>
<name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} |
{stop, Reason}</name>
- <fsummary> Makes necessary initializations and returns the
+ <fsummary>Makes necessary initializations and returns the
initial channel state if the initializations succeed.</fsummary>
<type>
- <v> Args = term() </v>
- <d> Last argument to ssh_channel:start_link/4.</d>
- <v> State = term() </v>
- <v> Reason = term() </v>
+ <v>Args = term()</v>
+ <d>Last argument to <c>ssh_channel:start_link/4</c>.</d>
+ <v>State = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p> Makes necessary initializations and returns the initial channel
+ <p>Makes necessary initializations and returns the initial channel
state if the initializations succeed.
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>. </p>
</desc>
</func>
<func>
<name>Module:handle_call(Msg, From, State) -> Result</name>
- <fsummary> Handles messages sent by calling
- <c>ssh_channel:call/[2,3]</c></fsummary>
+ <fsummary>Handles messages sent by calling
+ <c>ssh_channel:call/[2,3]</c>.</fsummary>
<type>
<v>Msg = term()</v>
- <v>From = opaque to the user should be used as argument to
- ssh_channel:reply/2</v>
+ <v>From = opaque()</v>
+ <d>Is to be used as argument to
+ <seealso marker="#reply-2">ssh_channel:reply/2</seealso></d>
<v>State = term()</v>
<v>Result = {reply, Reply, NewState} | {reply, Reply, NewState, timeout()}
| {noreply, NewState} | {noreply , NewState, timeout()}
| {stop, Reason, Reply, NewState} | {stop, Reason, NewState} </v>
- <v>Reply = term() - will be the return value of ssh_channel:call/[2,3]</v>
+ <v>Reply = term()</v>
+ <d>Will be the return value of <seealso marker="#call-2">ssh_channel:call/[2,3]</seealso></d>
<v>NewState = term()</v>
<v>Reason = term()</v>
</type>
@@ -311,15 +330,15 @@
<p>Handles messages sent by calling
<seealso marker="#call-2">ssh_channel:call/[2,3]</seealso>
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs,, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
</desc>
</func>
<func>
<name>Module:handle_cast(Msg, State) -> Result</name>
- <fsummary> Handles messages sent by calling
- <c>ssh_channel:cact/2</c></fsummary>
+ <fsummary>Handles messages sent by calling
+ <c>ssh_channel:cact/2</c>.</fsummary>
<type>
<v>Msg = term()</v>
<v>State = term()</v>
@@ -329,11 +348,11 @@
<v>Reason = term()</v>
</type>
<desc>
- <p> Handles messages sent by calling
- <c>ssh_channel:cast/2</c>
+ <p>Handles messages sent by calling
+ <c>ssh_channel:cast/2</c>.
</p>
- <p>For more detailed information on timeouts see the section
- <seealso marker="#cb_timeouts">CALLBACK TIMEOUTS</seealso>. </p>
+ <p>For more detailed information on time-outs, see Section
+ <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
</desc>
</func>
@@ -341,33 +360,33 @@
<name>Module:handle_msg(Msg, State) -> {ok, State} |
{stop, ChannelId, State}</name>
- <fsummary> Handle other messages than SSH connection protocol,
- call or cast messages sent to the channel.</fsummary>
+ <fsummary>Handles other messages than SSH connection protocol,
+ call, or cast messages sent to the channel.</fsummary>
<type>
<v>Msg = timeout | term()</v>
<v>ChannelId = ssh_channel_id()</v>
<v>State = term() </v>
</type>
<desc>
- <p>Handle other messages than ssh connection protocol, call or
+ <p>Handles other messages than SSH Connection Protocol, call, or
cast messages sent to the channel.
</p>
- <p> Possible erlang 'EXIT'-messages should be handled by this
- function and all channels should handle the following message.</p>
+ <p>Possible Erlang 'EXIT' messages is to be handled by this
+ function and all channels are to handle the following message.</p>
<taglist>
<tag><c><![CDATA[{ssh_channel_up, ssh_channel_id(),
ssh_connection_ref()}]]></c></tag>
- <item>This is the first messages that will be received by
- the channel, it is sent just before the <seealso
+ <item><p>This is the first message that the channel receives.
+ It is sent just before the <seealso
marker="#init-1">ssh_channel:init/1</seealso> function
- returns successfully. This is especially useful if the
+ returns successfully. This is especially useful if the
server wants to send a message to the client without first
receiving a message from it. If the message is not
- useful for your particular scenario just ignore it by
- immediately returning {ok, State}.
- </item>
+ useful for your particular scenario, ignore it by
+ immediately returning <c>{ok, State}</c>.
+ </p></item>
</taglist>
</desc>
</func>
@@ -375,42 +394,44 @@
<func>
<name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop,
ChannelId, State}</name>
- <fsummary> Handles ssh connection protocol messages. </fsummary>
+ <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary>
<type>
- <v>Msg = <seealso marker="ssh_connection"> ssh_connection:event() </seealso> </v>
+ <v>Msg = ssh_connection:event()</v>
<v>ChannelId = ssh_channel_id()</v>
<v>State = term()</v>
</type>
<desc>
- <p> Handles SSH connection protocol messages that may need
- service specific attention.
+ <p>Handles SSH Connection Protocol messages that may need
+ service-specific attention. For details,
+ see <seealso marker="ssh_connection"> ssh_connection:event()</seealso>.
</p>
- <p> The following message is completely taken care of by the
- SSH channel behavior</p>
+ <p>The following message is taken care of by the
+ <c>ssh_channel</c> behavior.</p>
<taglist>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
- <item> The channel behavior will send a close message to the
- other side if such a message has not already been sent and
- then terminate the channel with reason normal.</item>
+ <item><p>The channel behavior sends a close message to the
+ other side, if such a message has not already been sent.
+ Then it terminates the channel with reason <c>normal</c>.</p></item>
</taglist>
</desc>
</func>
<func>
<name>Module:terminate(Reason, State) -> _</name>
- <fsummary> </fsummary>
+ <fsummary>Does cleaning up before channel process termination.
+ </fsummary>
<type>
<v>Reason = term()</v>
<v>State = term()</v>
</type>
<desc>
<p>This function is called by a channel process when it is
- about to terminate. Before this function is called <seealso
+ about to terminate. Before this function is called, <seealso
marker="ssh_connection#close-2"> ssh_connection:close/2
- </seealso> will be called if it has not been called earlier.
- This function should do any necessary cleaning
+ </seealso> is called, if it has not been called earlier.
+ This function does any necessary cleaning
up. When it returns, the channel process terminates with
reason <c>Reason</c>. The return value is ignored.
</p>
diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml
index f3d05a8980..6b8932e5a7 100644
--- a/lib/ssh/doc/src/ssh_client_key_api.xml
+++ b/lib/ssh/doc/src/ssh_client_key_api.xml
@@ -9,116 +9,127 @@
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_client_key_api</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_client_key_api</module>
<modulesummary>
-behaviour(ssh_client_key_api).
</modulesummary>
<description>
- <p> Behavior describing the API for an SSH client's public key handling.
- By implementing the callbacks defined.
- in this behavior it is possible to customize the SSH client's public key
- handling. By default the SSH application implements this behavior
- with help of the standard openssh files, see <seealso marker="SSH_app"> ssh(6)</seealso>. </p>
+ <p>Behavior describing the API for public key handling of an SSH client. By implementing
+ the callbacks defined in this behavior, the public key handling of an SSH client can
+ be customized. By default the <c>ssh</c> application implements this behavior
+ with help of the standard OpenSSH files,
+ see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type. For more details on public key data types
- see the <seealso marker="public_key:public_key_records"> public_key user's guide.</seealso>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both. For more details on public key data types,
+ refer to Section 2 Public Key Records in the
+ <seealso marker="public_key:public_key_records"> public_key user's guide:</seealso>
</p>
-
- <p> boolean() = true | false</p>
- <p> string() = [byte()] </p>
- <p> public_key() = #'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</p>
- <p> private_key() = #'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</p>
- <p> public_key_algorithm() = 'ssh-rsa'| 'ssh-dss' | atom()</p>
-
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>public_key() =</c></tag>
+ <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <tag><c>private_key() =</c></tag>
+ <item><p><c>#'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</c></p></item>
+ <tag><c>public_key_algorithm() =</c></tag>
+ <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>Module:add_host_key(HostNames, Key, ConnectOptions) -> ok | {error, Reason}</name>
- <fsummary>Adds a host key to the set of trusted host keys</fsummary>
+ <fsummary>Adds a host key to the set of trusted host keys.</fsummary>
<type>
<v>HostNames = string()</v>
- <d>Description of the host that owns the <c>PublicKey</c></d>
+ <d>Description of the host that owns the <c>PublicKey</c>.</d>
- <v>Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
+ <v>Key = public_key()</v>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added.</d>
- <v>ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
- <v>Reason = term() </v>
+ <v>ConnectOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>Reason = term().</v>
</type>
<desc>
- <p> Adds a host key to the set of trusted host keys</p>
+ <p>Adds a host key to the set of trusted host keys.</p>
</desc>
</func>
<func>
<name>Module:is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name>
- <fsummary>Checks if a host key is trusted</fsummary>
+ <fsummary>Checks if a host key is trusted.</fsummary>
<type>
<v>Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added.</d>
<v>Host = string()</v>
- <d>Description of the host</d>
+ <d>Description of the host.</d>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa'| 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa'| 'ssh-dss'</c>, but more algorithms
can be handled.</d>
- <v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>ConnectOptions = proplists:proplist() </v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso>.</d>
- <v> Result = boolean()</v>
+ <v>Result = boolean()</v>
</type>
<desc>
- <p>Checks if a host key is trusted</p>
+ <p>Checks if a host key is trusted.</p>
</desc>
</func>
<func>
<name>Module:user_key(Algorithm, ConnectOptions) ->
{ok, PrivateKey} | {error, Reason}</name>
- <fsummary>Fetches the users "public key" matching the <c>Algorithm</c>.</fsummary>
+ <fsummary>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</fsummary>
<type>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa'| 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa'| 'ssh-dss'</c> but more algorithms
can be handled.</d>
- <v> ConnectOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
+ <v>ConnectOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso></d>
- <v> PrivateKey = private_key()</v>
- <d> The private key of the user matching the <c>Algorithm</c></d>
+ <v>PrivateKey = private_key()</v>
+ <d>Private key of the user matching the <c>Algorithm</c>.</d>
- <v>Reason = term() </v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Fetches the users "public key" matching the <c>Algorithm</c>.
- <note><p>The private key contains the public key</p></note>
- </p>
+ <p>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</p>
+ <note><p>The private key contains the public key.</p></note>
+
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index 5e2926dfa6..150d46a9a2 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -5,175 +5,194 @@
<header>
<copyright>
<year>2008</year>
- <year>2014</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_connection</title>
+ <prepared></prepared>
+ <docno></docno>
<date></date>
+ <rev></rev>
</header>
<module>ssh_connection</module>
- <modulesummary>This module provides API functions to send <url href="http://www.ietf.org/rfc/rfc4254.txt"> SSH Connection Protocol </url>
- events to the other side of an SSH channel.
+ <modulesummary>
+ This module provides API functions to send SSH Connection Protocol
+ events to the other side of an SSH channel.
</modulesummary>
<description>
- <p>The SSH Connection Protocol is used by clients and servers
- (i.e. SSH channels) to communicate over the SSH connection. The
- API functions in this module sends SSH Connection Protocol events
- that are received as messages by the remote channel.
- In the case that the receiving channel is an Erlang process the
- message will be on the following format
- <c><![CDATA[{ssh_cm, ssh_connection_ref(), ssh_event_msg()}]]></c>. If the <seealso
- marker="ssh_channel">ssh_channel</seealso> behavior is used to
- implement the channel process these will be handled by
- <seealso
- marker="ssh_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2 </seealso>.</p>
+ <p>The <url href="http://www.ietf.org/rfc/rfc4254.txt">SSH Connection Protocol</url>
+ is used by clients and servers, that is, SSH channels, to communicate over the
+ SSH connection. The API functions in this module send SSH Connection Protocol events,
+ which are received as messages by the remote channel.
+ If the receiving channel is an Erlang process, the
+ messages have the format
+ <c><![CDATA[{ssh_cm, ssh_connection_ref(), ssh_event_msg()}]]></c>.
+ If the <seealso marker="ssh_channel">ssh_channel</seealso> behavior is used to
+ implement the channel process, these messages are handled by
+ <seealso marker="ssh_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2</seealso>.</p>
</description>
<section>
- <title>DATA TYPES </title>
-
- <p>Type definitions that are used more than once in this module and/or
- abstractions to indicate the intended use of the data type:</p>
-
- <p><c>boolean() = true | false </c></p>
- <p><c>string() = list of ASCII characters</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
- <p><c>ssh_connection_ref() - opaque to the user returned by
- ssh:connect/3 or sent to an SSH channel processes</c></p>
- <p><c>ssh_channel_id() = integer() </c></p>
- <p><c>ssh_data_type_code() = 1 ("stderr") | 0 ("normal") are
- currently valid values see</c> <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 5.2.</p>
- <p><c>ssh_request_status() = success | failure</c></p>
- <p><c>event() = {ssh_cm, ssh_connection_ref(), ssh_event_msg()} </c></p>
- <p><c>ssh_event_msg() = data_events() | status_events() | terminal_events() </c></p>
- <p><c>reason() = timeout | closed </c></p>
+ <title>DATA TYPES</title>
+
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both:</p>
+
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false </c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p>list of ASCII characters</p></item>
+ <tag><c>timeout() =</c></tag>
+ <item><p><c>infinity | integer()</c> in milliseconds</p></item>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() -as returned by
+ <c>ssh:connect/3</c> or sent to an SSH channel processes</p></item>
+ <tag><c>ssh_channel_id() =</c></tag>
+ <item><p><c>integer()</c></p></item>
+ <tag><c>ssh_data_type_code() =</c></tag>
+ <item><p><c>1</c> ("stderr") | <c>0</c> ("normal") are
+ valid values, see
+ <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> Section 5.2.</p></item>
+ <tag><c>ssh_request_status() =</c></tag>
+ <item><p> <c>success | failure</c></p></item>
+ <tag><c>event() =</c></tag>
+ <item><p><c>{ssh_cm, ssh_connection_ref(), ssh_event_msg()}</c></p></item>
+ <tag><c>ssh_event_msg() =</c></tag>
+ <item><p><c>data_events() | status_events() | terminal_events()</c></p></item>
+ <tag><c>reason() =</c></tag>
+ <item><p><c>timeout | closed</c></p></item>
+ </taglist>
<taglist>
- <tag><b>data_events()</b></tag>
+ <tag><em>data_events()</em></tag>
<item>
<taglist>
- <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}]]></c></tag>
- <item> Data has arrived on the channel. This event is sent as
- result of calling <seealso marker="ssh_connection#send-3"> ssh_connection:send/[3,4,5] </seealso></item>
+ <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}]]></c></tag>
+ <item><p>Data has arrived on the channel. This event is sent as a
+ result of calling <seealso marker="ssh_connection#send-3">
+ ssh_connection:send/[3,4,5]</seealso>.</p></item>
<tag><c><![CDATA[{eof, ssh_channel_id()}]]></c></tag>
- <item>Indicates that the other side will not send any more
- data. This event is sent as result of calling <seealso
- marker="ssh_connection#send_eof-2"> ssh_connection:send_eof/2</seealso>
- </item>
+ <item><p>Indicates that the other side sends no more data.
+ This event is sent as a result of calling <seealso
+ marker="ssh_connection#send_eof-2"> ssh_connection:send_eof/2</seealso>.
+ </p></item>
</taglist>
</item>
- <tag><b>status_events()</b></tag>
+ <tag><em>status_events()</em></tag>
<item>
<taglist>
<tag><c><![CDATA[{signal, ssh_channel_id(), ssh_signal()}]]></c></tag>
- <item>A signal can be delivered to the remote process/service
- using the following message. Some systems will not support
- signals, in which case they should ignore this message. There is
- currently no funtion to generate this event as the signals
- refered to are on OS-level and not something generated by an
- Erlang program.</item>
-
- <tag><c><![CDATA[{exit_signal, ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg,
- string() = LanguageString}]]></c></tag>
-
- <item>A remote execution may terminate violently due to a signal
- then this message may be received. For details on valid string
- values see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url> section 6.10. Special case of the signals
- mentioned above.</item>
-
- <tag><c><![CDATA[{exit_status, ssh_channel_id(), integer() = ExitStatus}]]></c></tag>
- <item> When the command running at the other end terminates, the
+ <item><p>A signal can be delivered to the remote process/service
+ using the following message. Some systems do not support
+ signals, in which case they are to ignore this message. There is
+ currently no function to generate this event as the signals
+ referred to are on OS-level and not something generated by an
+ Erlang program.</p></item>
+
+ <tag><c><![CDATA[{exit_signal, ssh_channel_id(), ExitSignal :: string(), ErrorMsg ::string(),
+ LanguageString :: string()}]]></c></tag>
+
+ <item><p>A remote execution can terminate violently because of a signal.
+ Then this message can be received. For details on valid string
+ values, see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
+ Section 6.10, which shows a special case of these signals.</p></item>
+
+ <tag><c><![CDATA[{exit_status, ssh_channel_id(), ExitStatus :: integer()}]]></c></tag>
+ <item><p>When the command running at the other end terminates, the
following message can be sent to return the exit status of the
- command. A zero 'exit_status' usually means that the command
- terminated successfully. This event is sent as result of calling
+ command. A zero <c>exit_status</c> usually means that the command
+ terminated successfully. This event is sent as a result of calling
<seealso marker="ssh_connection#exit_status-3">
- ssh_connection:exit_status/3</seealso></item>
+ ssh_connection:exit_status/3</seealso>.</p></item>
<tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
- <item> This event is sent as result of calling
- <seealso marker="ssh_connection#close-2">ssh_connection:close/2</seealso> Both the handling of this
- event and sending of it will be taken care of by the
- <seealso marker="ssh_channel">ssh_channel</seealso> behavior.</item>
+ <item><p>This event is sent as a result of calling
+ <seealso marker="ssh_connection#close-2">ssh_connection:close/2</seealso>.
+ Both the handling of this event and sending it are taken care of by the
+ <seealso marker="ssh_channel">ssh_channel</seealso> behavior.</p></item>
</taglist>
</item>
- <tag><b>terminal_events()</b></tag>
+ <tag><em>terminal_events()</em></tag>
<item>
- <p> Channels implementing a shell and command execution on the
- server side should handle the following messages that may be sent by client channel processes. </p>
+ <p>Channels implementing a shell and command execution on the
+ server side are to handle the following messages that can be sent by client-
+ channel processes.</p>
- <note> <p>Events that includes a <c> WantReply</c> expects the event handling
- process to call <seealso marker="ssh_connection#reply_request-4">ssh_connection:reply_request/4</seealso>
- with the boolean value of <c> WantReply</c> as the second
- argument. </p></note>
+ <p>Events that include a <c>WantReply</c> expect the event handling
+ process to call <seealso marker="ssh_connection#reply_request-4">
+ ssh_connection:reply_request/4</seealso>
+ with the boolean value of <c>WantReply</c> as the second argument.</p>
<taglist>
- <tag><c><![CDATA[{env, ssh_channel_id(), boolean() = WantReply,
- string() = Var, string() = Value}]]></c></tag>
- <item> Environment variables may be passed to the shell/command
- to be started later. This event is sent as result of calling <seealso
- marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>
- </item>
+ <tag><c><![CDATA[{env, ssh_channel_id(), WantReply :: boolean(),
+ Var ::string(), Value :: string()}]]></c></tag>
+ <item><p>Environment variables can be passed to the shell/command
+ to be started later. This event is sent as a result of calling <seealso
+ marker="ssh_connection#setenv-5"> ssh_connection:setenv/5</seealso>.
+ </p></item>
<tag><c><![CDATA[{pty, ssh_channel_id(),
- boolean() = WantReply, {string() = Terminal, integer() = CharWidth,
- integer() = RowHeight, integer() = PixelWidth, integer() = PixelHeight,
- [{atom() | integer() = Opcode,
- integer() = Value}] = TerminalModes}}]]></c></tag>
- <item>A pseudo-terminal has been requested for the
- session. Terminal is the value of the TERM environment
- variable value (e.g., vt100). Zero dimension parameters must
- be ignored. The character/row dimensions override the pixel
- dimensions (when nonzero). Pixel dimensions refer to the
- drawable area of the window. The <c>Opcode</c> in the
+ WantReply :: boolean(), {Terminal :: string(), CharWidth :: integer(),
+ RowHeight :: integer(), PixelWidth :: integer(), PixelHeight :: integer(),
+ TerminalModes :: [{Opcode :: atom() | integer(),
+ Value :: integer()}]}}]]></c></tag>
+ <item><p>A pseudo-terminal has been requested for the
+ session. <c>Terminal</c> is the value of the TERM environment
+ variable value, that is, <c>vt100</c>. Zero dimension parameters must
+ be ignored. The character/row dimensions override the pixel
+ dimensions (when non-zero). Pixel dimensions refer to the
+ drawable area of the window. <c>Opcode</c> in the
<c>TerminalModes</c> list is the mnemonic name, represented
- as an lowercase erlang atom, defined in
- <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254 </url> section 8.
- It may also be an opcode if the mnemonic name is not listed in the
- RFC. Example <c>OP code: 53, mnemonic name ECHO erlang atom:
- echo</c>.This event is sent as result of calling <seealso
- marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso></item>
-
- <tag><c><![CDATA[{shell, boolean() = WantReply}]]></c></tag>
- <item> This message will request that the user's default shell
- be started at the other end. This event is sent as result of calling <seealso
- marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>
- </item>
-
- <tag><c><![CDATA[{window_change, ssh_channel_id(), integer() = CharWidth,
- integer() = RowHeight, integer() = PixWidth, integer() = PixHeight}]]></c></tag>
- <item> When the window (terminal) size changes on the client
- side, it MAY send a message to the server side to inform it of
- the new dimensions. There is currently no API function to generate this
- event.</item>
+ as a lowercase Erlang atom, defined in
+ <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>, Section 8.
+ It can also be an <c>Opcode</c> if the mnemonic name is not listed in the
+ RFC. Example: <c>OP code: 53, mnemonic name ECHO erlang atom:
+ echo</c>. This event is sent as a result of calling <seealso
+ marker="ssh_connection#ptty_alloc/4">ssh_connection:ptty_alloc/4</seealso>.</p></item>
+
+ <tag><c><![CDATA[{shell, WantReply :: boolean()}]]></c></tag>
+ <item><p>This message requests that the user default shell
+ is started at the other end. This event is sent as a result of calling
+ <seealso marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>.
+ </p></item>
+
+ <tag><c><![CDATA[{window_change, ssh_channel_id(), CharWidth() :: integer(),
+ RowHeight :: integer(), PixWidth :: integer(), PixHeight :: integer()}]]></c></tag>
+ <item><p>When the window (terminal) size changes on the client
+ side, it <em>can</em> send a message to the server side to inform it of
+ the new dimensions. No API function generates this event.</p></item>
<tag><c><![CDATA[{exec, ssh_channel_id(),
- boolean() = WantReply, string() = Cmd}]]></c></tag>
- <item> This message will request that the server starts
- execution of the given command. This event is sent as result of calling <seealso
- marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>
- </item>
+ WantReply :: boolean(), Cmd :: string()}]]></c></tag>
+ <item><p>This message requests that the server starts
+ execution of the given command. This event is sent as a result of calling <seealso
+ marker="ssh_connection#exec-4">ssh_connection:exec/4 </seealso>.
+ </p></item>
</taglist>
</item>
</taglist>
@@ -183,80 +202,83 @@
<func>
<name>adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok</name>
- <fsummary>Adjusts the SSH flowcontrol window. </fsummary>
+ <fsummary>Adjusts the SSH flow control window.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id() </v>
- <v> NumOfBytes = integer()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>NumOfBytes = integer()</v>
</type>
<desc>
- <p>Adjusts the SSH flowcontrol window. This shall be done by both client and server side channel processes.</p>
+ <p>Adjusts the SSH flow control window. This is to be done by both the
+ client- and server-side channel processes.</p>
- <note><p>Channels implemented with the <seealso marker="ssh_channel"> ssh_channel
- behavior</seealso> will normaly not need to call this function as flow control
- will be handled by the behavior. The behavior will adjust the window every time
+ <note><p>Channels implemented with the <seealso marker="ssh_channel"> ssh_channel</seealso>
+ behavior do not normally need to call this function as flow control
+ is handled by the behavior. The behavior adjusts the window every time
the callback <seealso marker="ssh_channel#Module:handle_ssh_msg-2">
- handle_ssh_msg/2 </seealso> has returned after processing channel data</p> </note>
+ handle_ssh_msg/2</seealso> returns after processing channel data.</p></note>
</desc>
</func>
<func>
<name>close(ConnectionRef, ChannelId) -> ok</name>
- <fsummary>Sends a close message on the channel <c>ChannelId</c>. </fsummary>
+ <fsummary>Sends a close message on the channel <c>ChannelId</c>.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p>A server or client channel process can choose to close their session by sending a close event.
+ <p>A server- or client-channel process can choose to close their session by
+ sending a close event.
</p>
- <note><p>This function will be called by the ssh_channel
- behavior when the channel is terminated see <seealso
- marker="ssh_channel"> ssh_channel(3) </seealso> so channels implemented with the
- behavior should not call this function explicitly.</p></note>
+ <note><p>This function is called by the <c>ssh_channel</c>
+ behavior when the channel is terminated, see <seealso
+ marker="ssh_channel"> ssh_channel(3)</seealso>. Thus, channels implemented
+ with the behavior are not to call this function explicitly.</p></note>
</desc>
</func>
<func>
- <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | {error, reason()} </name>
- <fsummary>Request that the server start the execution of the given command. </fsummary>
+ <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Requests that the server starts the execution of the given command.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Command = string()</v>
- <v>Timeout = timeout() </v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Command = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p>Should be called by a client channel process to request that the server starts execution of the
- given command, the result will be several messages according to the following pattern. Note
- that the last message will be a channel close message, as the exec request is a one time
- execution that closes the channel when it is done.</p>
+ <p>Is to be called by a client-channel process to request that the server starts
+ executing the given command. The result is several messages according to the
+ following pattern. The last message is a channel close message, as the <c>exec</c>
+ request is a one-time execution that closes the channel when it is done.</p>
<taglist>
- <tag><c> N x {ssh_cm, ssh_connection_ref(),
- {data, ssh_channel_id(), ssh_data_type_code(), binary() = Data}} </c></tag>
- <item>The result of executing the command may be only one line
- or thousands of lines depending on the command.</item>
+ <tag><c>N x {ssh_cm, ssh_connection_ref(),
+ {data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}}</c></tag>
+ <item><p>The result of executing the command can be only one line
+ or thousands of lines depending on the command.</p></item>
<tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {eof, ssh_channel_id()}}</c></tag>
- <item>Indicates that no more data will be sent.</item>
+ <item><p>Indicates that no more data is to be sent.</p></item>
<tag><c>0 or 1 x {ssh_cm,
ssh_connection_ref(), {exit_signal,
- ssh_channel_id(), string() = ExitSignal, string() = ErrorMsg, string() = LanguageString}}</c></tag>
- <item>Not all systems send signals. For details on valid string
- values see RFC 4254 section 6.10 </item>
+ ssh_channel_id(), ExitSignal :: string(), ErrorMsg :: string(), LanguageString :: string()}}</c></tag>
+ <item><p>Not all systems send signals. For details on valid string
+ values, see RFC 4254, Section 6.10</p></item>
<tag><c>0 or 1 x {ssh_cm, ssh_connection_ref(), {exit_status,
- ssh_channel_id(), integer() = ExitStatus}}</c></tag>
- <item>It is recommended by the <c>ssh connection protocol</c> that this
- message shall be sent, but that may not always be the case.</item>
+ ssh_channel_id(), ExitStatus :: integer()}}</c></tag>
+ <item><p>It is recommended by the SSH Connection Protocol to send this
+ message, but that is not always the case.</p></item>
- <tag><c> 1 x {ssh_cm, ssh_connection_ref(),
+ <tag><c>1 x {ssh_cm, ssh_connection_ref(),
{closed, ssh_channel_id()}}</c></tag>
- <item>Indicates that the ssh channel started for the
- execution of the command has now been shutdown.</item>
+ <item><p>Indicates that the <c>ssh_channel</c> started for the
+ execution of the command has now been shut down.</p></item>
</taglist>
</desc>
</func>
@@ -265,78 +287,72 @@
<name>exit_status(ConnectionRef, ChannelId, Status) -> ok</name>
<fsummary>Sends the exit status of a command to the client.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Status = integer()</v>
+ <v>ConnectionRef = ssh_connection_ref() </v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Status = integer()</v>
</type>
<desc>
- <p>Should be called by a server channel process to sends the exit status of a command to the client.</p>
+ <p>Is to be called by a server-channel process to send the exit status of a command
+ to the client.</p>
</desc>
</func>
<func>
- <name>ptty_alloc(ConnectionRef, ChannelId, Options) -> </name>
- <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | {error, reason()} </name>
- <fsummary>Send status replies to requests that want such replies. </fsummary>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options) -></name>
+ <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Sends an SSH Connection Protocol <c>pty_req</c>,
+ to allocate a pseudo-terminal.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Options = proplists:proplist()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Options = proplists:proplist()</v>
</type>
<desc>
- <p> Sends a SSH Connection Protocol pty_req, to allocate a pseudo tty.
- Should be called by a SSH client process.
- Options are:
- </p>
+ <p>Sends an SSH Connection Protocol <c>pty_req</c>, to allocate a pseudo-terminal.
+ Is to be called by an SSH client process.</p>
+ <p>Options:</p>
<taglist>
<tag>{term, string()}</tag>
- <item>
- Defaults to os:getenv("TERM") or "vt100" if it is undefined.
- </item>
+ <item><p>Defaults to <em>os:getenv("TERM")</em> or <em>vt100</em>
+ if it is undefined.</p></item>
+
<tag>{width, integer()}</tag>
- <item>
- Defaults to 80 if pixel_width is not defined.
- </item>
+ <item><p>Defaults to 80 if <c>pixel_width</c> is not defined.</p></item>
+
<tag>{height, integer()}</tag>
- <item>
- Defaults to 24 if pixel_height is not defined.
- </item>
+ <item><p>Defaults to 24 if <c>pixel_height</c> is not defined.</p></item>
+
<tag>{pixel_width, integer()}</tag>
- <item>
- Is disregarded if width is defined.
- </item>
+ <item><p>Is disregarded if <c>width</c> is defined.</p></item>
+
<tag>{pixel_height, integer()}</tag>
- <item>
- Is disregarded if height is defined.
- </item>
+ <item><p>Is disregarded if <c>height</c> is defined.</p></item>
+
<tag>{pty_opts, [{posix_atom(), integer()}]}</tag>
- <item>
- Option may be an empty list, otherwise
- see possible POSIX names in section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>.
+ <item><p>Option can be an empty list. Otherwise, see possible <em>POSIX</em> names
+ in Section 8 in <url href="http://www.ietf.org/rfc/rfc4254.txt"> RFC 4254</url>.</p>
</item>
</taglist>
-
</desc>
</func>
- <func>
+ <func>
<name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name>
- <fsummary>Send status replies to requests that want such replies. </fsummary>
+ <fsummary>Sends status replies to requests that want such replies.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> WantReply = boolean()</v>
- <v> Status = ssh_request_status() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>WantReply = boolean()</v>
+ <v>Status = ssh_request_status()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
<p>Sends status replies to requests where the requester has
- stated that they want a status report e.i .<c> WantReply = true</c>,
- if <c> WantReply</c> is false calling this function will be a
- "noop". Should be called while handling an ssh connection
- protocol message containing a <c>WantReply</c> boolean
- value.
- </p>
+ stated that it wants a status report, that is, <c>WantReply = true</c>.
+ If <c>WantReply</c> is <c>false</c>, calling this function becomes a
+ "noop". Is to be called while handling an SSH Connection
+ Protocol message containing a <c>WantReply</c> boolean value.</p>
</desc>
</func>
@@ -346,98 +362,103 @@
<name>send(ConnectionRef, ChannelId, Type, Data) -></name>
<name>send(ConnectionRef, ChannelId, Type, Data, TimeOut) ->
ok | {error, timeout} | {error, closed}</name>
- <fsummary>Sends channel data </fsummary>
+ <fsummary>Sends channel data.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Data = binary()</v>
- <v> Type = ssh_data_type_code()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Data = binary()</v>
+ <v>Type = ssh_data_type_code()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p>Should be called by client- and server channel processes to send data to each other.
+ <p>Is to be called by client- and server-channel processes to send data to each other.
+ </p>
+ <p>The function <seealso marker="ssh:ssh_connection#subsystem/4">subsystem/4</seealso> and subsequent
+ calls of <c>send/3,4,5</c> must be executed in the same process.
</p>
</desc>
</func>
<func>
<name>send_eof(ConnectionRef, ChannelId) -> ok | {error, closed}</name>
- <fsummary>Sends eof on the channel <c>ChannelId</c>. </fsummary>
+ <fsummary>Sends EOF on channel <c>ChannelId</c>.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p>Sends eof on the channel <c>ChannelId</c>.
- </p>
+ <p>Sends EOF on channel <c>ChannelId</c>.</p>
</desc>
</func>
<func>
- <name>session_channel(ConnectionRef, Timeout) -> </name>
+ <name>session_channel(ConnectionRef, Timeout) -></name>
<name>session_channel(ConnectionRef, InitialWindowSize,
MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, reason()}</name>
- <fsummary>Opens a channel for a ssh session. </fsummary>
+ <fsummary>Opens a channel for an SSH session.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref()</v>
- <v> InitialWindowSize = integer() </v>
- <v> MaxPacketSize = integer() </v>
- <v> Timeout = timeout()</v>
- <v> Reason = term() </v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>InitialWindowSize = integer()</v>
+ <v>MaxPacketSize = integer()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
<p>Opens a channel for an SSH session. The channel id returned from this function
- is the id used as input to the other funtions in this module.
- </p>
+ is the id used as input to the other functions in this module.</p>
</desc>
</func>
<func>
- <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | {error, reason()} </name>
- <fsummary> Environment variables may be passed to the
+ <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Environment variables can be passed to the
shell/command to be started later.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Var = string()</v>
- <v> Value = string()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Var = string()</v>
+ <v>Value = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p> Environment variables may be passed before starting the
- shell/command. Should be called by a client channel processes.
- </p>
+ <p>Environment variables can be passed before starting the
+ shell/command. Is to be called by a client channel processes.</p>
</desc>
</func>
<func>
<name>shell(ConnectionRef, ChannelId) -> ssh_request_status() | {error, closed}
</name>
- <fsummary> Requests that the user's default shell (typically
- defined in /etc/passwd in UNIX systems) shall be executed at the server
- end. </fsummary>
+ <fsummary>Requests that the user default shell (typically defined in
+ /etc/passwd in Unix systems) is to be executed at the server end.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
</type>
<desc>
- <p> Should be called by a client channel process to request that the user's default shell (typically
- defined in /etc/passwd in UNIX systems) shall be executed at the server end.
- </p>
+ <p>Is to be called by a client channel process to request that the user default
+ shell (typically defined in /etc/passwd in Unix systems) is executed
+ at the server end.</p>
</desc>
</func>
<func>
- <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | {error, reason()} </name>
- <fsummary> </fsummary>
+ <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() |
+ {error, reason()}</name>
+ <fsummary>Requests to execute a predefined subsystem on the server.</fsummary>
<type>
- <v> ConnectionRef = ssh_connection_ref() </v>
- <v> ChannelId = ssh_channel_id()</v>
- <v> Subsystem = string()</v>
- <v> Timeout = timeout()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ChannelId = ssh_channel_id()</v>
+ <v>Subsystem = string()</v>
+ <v>Timeout = timeout()</v>
</type>
<desc>
- <p> Should be called by a client channel process for requesting to execute a predefined subsystem on the server.
+ <p>Is to be called by a client-channel process for requesting to execute a predefined
+ subsystem on the server.
+ </p>
+ <p>The function <c>subsystem/4</c> and subsequent calls of
+ <seealso marker="ssh:ssh_connection#send/3">send/3,4,5</seealso> must be executed in the same process.
</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml
index f7133e4ba5..a0694ca8d9 100644
--- a/lib/ssh/doc/src/ssh_server_key_api.xml
+++ b/lib/ssh/doc/src/ssh_server_key_api.xml
@@ -5,86 +5,100 @@
<header>
<copyright>
<year>2012</year>
- <year>2013</year>
+ <year>2015</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>ssh_server_key_api</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
</header>
<module>ssh_server_key_api</module>
<modulesummary>
-behaviour(ssh_server_key_api).
</modulesummary>
<description>
- <p> Behaviour describing the API for an SSH server's public key handling. By implementing the callbacks defined
- in this behavior it is possible to customize the SSH server's public key
- handling. By default the SSH application implements this behavior
- with help of the standard openssh files, see <seealso marker="SSH_app"> ssh(6)</seealso>.</p>
+ <p>Behaviour describing the API for public key handling of an SSH server. By implementing
+ the callbacks defined in this behavior, the public key handling of an SSH server can
+ be customized. By default the SSH application implements this behavior
+ with help of the standard OpenSSH files,
+ see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
<section>
- <title>DATA TYPES </title>
+ <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data
- type. For more details on public key data types
- see the <seealso marker="public_key:public_key_records"> public_key user's guide.</seealso>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data
+ type, or both. For more details on public key data types,
+ refer to Section 2 Public Key Records in the
+ <seealso marker="public_key:public_key_records"> public_key user's guide</seealso>.
</p>
- <p> boolean() = true | false</p>
- <p> string() = [byte()]</p>
- <p> public_key() = #'RSAPublicKey'{} | {integer(), #'Dss-Parms'{}} | term()</p>
- <p> private_key() = #'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</p>
- <p> public_key_algorithm() = 'ssh-rsa' | 'ssh-dss' | atom()</p>
+ <taglist>
+ <tag><c>boolean() =</c></tag>
+ <item><p><c>true | false</c></p></item>
+ <tag><c>string() =</c></tag>
+ <item><p><c>[byte()]</c></p></item>
+ <tag><c>public_key() =</c></tag>
+ <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <tag><c>private_key() =</c></tag>
+ <item><p><c>#'RSAPrivateKey'{} | #'DSAPrivateKey'{} | term()</c></p></item>
+ <tag><c>public_key_algorithm() =</c></tag>
+ <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ </taglist>
</section>
-
+
<funcs>
<func>
<name>Module:host_key(Algorithm, DaemonOptions) ->
{ok, Key} | {error, Reason}</name>
- <fsummary>Fetches the hosts private key </fsummary>
+ <fsummary>Fetches the host’s private key.</fsummary>
<type>
<v>Algorithm = public_key_algorithm()</v>
- <d> Host key algorithm. Should support 'ssh-rsa' | 'ssh-dss' but additional algorithms
+ <d>Host key algorithm. Is to support <c>'ssh-rsa' | 'ssh-dss'</c>, but more algorithms
can be handled.</d>
- <v> DaemonOptions = proplists:proplist() </v>
- <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
- <v> Key = private_key()</v>
- <d> The private key of the host matching the <c>Algorithm</c></d>
- <v>Reason = term() </v>
+ <v>DaemonOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
+ <v>Key = private_key()</v>
+ <d>Private key of the host matching the <c>Algorithm</c>.</d>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Fetches the hosts private key</p>
+ <p>Fetches the private key of the host.</p>
</desc>
</func>
<func>
<name>Module:is_auth_key(Key, User, DaemonOptions) -> Result</name>
- <fsummary> Checks if the user key is authorized</fsummary>
+ <fsummary>Checks if the user key is authorized.</fsummary>
<type>
- <v> Key = public_key() </v>
- <d> Normally an RSA or DSA public key but handling of other public keys can be added</d>
- <v> User = string()</v>
- <d> The user owning the public key</d>
- <v> DaemonOptions = proplists:proplist() </v>
- <d> Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso></d>
- <v> Result = boolean()</v>
+ <v>Key = public_key()</v>
+ <d>Normally an RSA or DSA public key, but handling of other public keys can be added</d>
+ <v>User = string()</v>
+ <d>User owning the public key.</d>
+ <v>DaemonOptions = proplists:proplist()</v>
+ <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
+ <v>Result = boolean()</v>
</type>
<desc>
- <p> Checks if the user key is authorized </p>
+ <p>Checks if the user key is authorized.</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index ab111562f9..c6ca0f161a 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -4,150 +4,196 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2014</year>
+ <year>2005</year><year>2015</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh_sftp</title>
<prepared>OTP</prepared>
+ <docno></docno>
<date>2005-09-22</date>
+ <rev></rev>
<file>ssh_sftp.sgml</file>
</header>
<module>ssh_sftp</module>
<modulesummary>SFTP client.</modulesummary>
<description>
- <p>This module implements an SFTP (SSH FTP) client. SFTP is a
+ <p>This module implements an SSH FTP (SFTP) client. SFTP is a
secure, encrypted file transfer service available for
SSH.</p>
</description>
<section>
- <title>DATA TYPES </title>
- <p>Type definitions that are used more than once in this module
- and/or abstractions to indicate the intended use of the data type:
+ <title>DATA TYPES</title>
+ <p>Type definitions that are used more than once in this module,
+ or abstractions to indicate the intended use of the data type, or both:
</p>
- <p><c>ssh_connection_ref() - opaque to the user
- returned by ssh:connect/3</c></p>
- <p><c>timeout() = infinity | integer() - in milliseconds.</c></p>
+
+ <taglist>
+ <tag><c>ssh_connection_ref() =</c></tag>
+ <item><p>opaque() - as returned by <c>ssh:connect/3</c></p></item>
+ <tag><c>timeout()</c></tag>
+ <item><p>= <c>infinity | integer() in milliseconds. Default infinity.</c></p></item>
+ </taglist>
</section>
<section>
- <title>TIMEOUTS </title>
- <p>If the request functions for the SFTP channel return {error, timeout}
- it does not guarantee that the request did not reach the server and was
- not performed, it only means that we did not receive an answer from the
- server within the time that was expected.</p>
+ <title>Time-outs</title>
+ <p>If the request functions for the SFTP channel return <c>{error, timeout}</c>,
+ it does not guarantee that the request never reached the server and was
+ not performed. It only means that no answer was received from the
+ server within the expected time.</p>
</section>
<funcs>
+ <func>
+ <name>apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, Reason}</name>
+ <fsummary>Reads asynchronously from an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>N = term()</v>
+ <v>Reason = term()</v>
+ </type>
+
+ <desc><p>The <c><![CDATA[apread]]></c> function reads from a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[aread]]></c> functions.</p>
+ <p><seealso marker="#apread-4">ssh_sftp:apread/4</seealso></p> </desc>
+ </func>
+
+ <func>
+ <name>apwrite(ChannelPid, Handle, Position, Data) -> ok | {error, Reason}</name>
+ <fsummary>Writes asynchronously to an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>Data = binary()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p><c><![CDATA[apwrite]]></c> writes on a specified position, combining
+ the <c><![CDATA[position]]></c> and <c><![CDATA[awrite]]></c> operations.</p>
+ <p><seealso marker="#awrite-3">ssh_sftp:awrite/3</seealso> </p></desc>
+ </func>
+
+ <func>
+ <name>aread(ChannelPid, Handle, Len) -> {async, N} | {error, Error}</name>
+ <fsummary>Reads asynchronously from an open file.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>N = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Reads from an open file, without waiting for the result. If the
+ handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where <c>N</c>
+ is a term guaranteed to be unique between calls of <c><![CDATA[aread]]></c>.
+ The actual data is sent as a message to the calling process. This
+ message has the form <c><![CDATA[{async_reply, N, Result}]]></c>, where
+ <c><![CDATA[Result]]></c> is the result from the read, either <c><![CDATA[{ok, Data}]]></c>,
+ <c><![CDATA[eof]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
+ </desc>
+ </func>
+
+
+
<func>
- <name>start_channel(ConnectionRef) -> </name>
- <name>start_channel(ConnectionRef, Options) -> </name>
- <name>start_channel(Host, Options) -></name>
- <name>start_channel(Host, Port, Options) -> {ok, Pid} | {ok, Pid, ConnectionRef} |
- {error, Reason}</name>
- <fsummary>Starts a SFTP client</fsummary>
+ <name>awrite(ChannelPid, Handle, Data) -> ok | {error, Reason}</name>
+ <fsummary>Writes asynchronously to an open file.</fsummary>
<type>
- <v>Host = string()</v>
- <v>ConnectionRef = ssh_connection_ref()</v>
- <v>Port = integer()</v>
- <v>Options = [{Option, Value}]</v>
+ <v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Len = integer()</v>
+ <v>Data = binary()</v>
+ <v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>If no connection reference is provided, a connection is set
- up and the new connection is returned. An SSH channel process
- is started to handle the communication with the SFTP server.
- The returned pid for this process should be used as input to
- all other API functions in this module.</p>
-
- <p>Options are:</p>
- <taglist>
- <tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
- <item>
- <p>The timeout is passed to the ssh_channel start function,
- and defaults to infinity.</p>
- </item>
- <tag>
- <p><c><![CDATA[{sftp_vsn, integer()}]]></c></p>
- </tag>
- <item>
- <p>
- Desired SFTP protocol version.
- The actual version will be the minimum of
- the desired version and the maximum supported
- versions by the SFTP server.
- </p>
- </item>
- </taglist>
- <p>All other options are directly passed to
- <seealso marker="ssh">ssh:connect/3</seealso> or ignored if a
- connection is already provided. </p>
+ <p>Writes to an open file, without waiting for the result. If the
+ handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where <c>N</c>
+ is a term guaranteed to be unique between calls of
+ <c><![CDATA[awrite]]></c>. The result of the <c><![CDATA[write]]></c> operation is sent
+ as a message to the calling process. This message has the form
+ <c><![CDATA[{async_reply, N, Result}]]></c>, where <c><![CDATA[Result]]></c> is the result
+ from the write, either <c><![CDATA[ok]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
</desc>
</func>
<func>
- <name>stop_channel(ChannelPid) -> ok</name>
- <fsummary>Stops the SFTP client channel.</fsummary>
+ <name>close(ChannelPid, Handle) -></name>
+ <name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Closes an open handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
+ <v>Handle = term()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Stops an SFTP channel. Does not close the SSH connetion.
- Use <seealso marker="ssh">ssh:close/1</seealso> to close it.</p>
+ <p>Closes a handle to an open file or directory on the server.</p>
</desc>
</func>
-
+
<func>
- <name>read_file(ChannelPid, File) -> </name>
- <name>read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, Reason}</name>
- <fsummary>Read a file</fsummary>
+ <name>delete(ChannelPid, Name) -></name>
+ <name>delete(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Deletes a file.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>File = string()</v>
- <v>Data = binary()</v>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
<v>Timeout = timeout()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Reads a file from the server, and returns the data in a binary,
- like <c><![CDATA[file:read_file/1]]></c>.</p>
+ <p>Deletes the file specified by <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#delete-1">file:delete/1</seealso></p>
</desc>
</func>
+
<func>
- <name>write_file(ChannelPid, File, Iolist) -> </name>
- <name>write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Write a file</fsummary>
+ <name>del_dir(ChannelPid, Name) -></name>
+ <name>del_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Deletes an empty directory.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>File = string()</v>
- <v>Iolist = iolist()</v>
+ <v>Name = string()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes a file to the server, like
- <c><![CDATA[file:write_file/2]]></c>. The file is created if
- it does not exist or is owerwritten if it does.</p>
+ <p>Deletes a directory specified by <c><![CDATA[Name]]></c>.
+ The directory must be empty before it can be successfully deleted.
+ </p>
</desc>
</func>
- <func>
- <name>list_dir(ChannelPid, Path) -> </name>
+
+ <func>
+ <name>list_dir(ChannelPid, Path) -></name>
<name>list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, Reason}</name>
- <fsummary>List directory</fsummary>
+ <fsummary>Lists the directory.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
@@ -161,10 +207,45 @@
filenames as a list of strings.</p>
</desc>
</func>
+
+ <func>
+ <name>make_dir(ChannelPid, Name) -></name>
+ <name>make_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Creates a directory.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
+ <v>Timeout = timeout()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Creates a directory specified by <c><![CDATA[Name]]></c>. <c><![CDATA[Name]]></c>
+ must be a full path to a new directory. The directory can only be
+ created in an existing directory.</p>
+ </desc>
+ </func>
+
<func>
- <name>open(ChannelPid, File, Mode) -> </name>
+ <name>make_symlink(ChannelPid, Name, Target) -></name>
+ <name>make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Creates a symbolic link.</fsummary>
+ <type>
+ <v>ChannelPid = pid()</v>
+ <v>Name = string()</v>
+ <v>Target = string()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Creates a symbolic link pointing to <c><![CDATA[Target]]></c> with the
+ name <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#make_symlink-2">file:make_symlink/2</seealso></p>
+ </desc>
+ </func>
+
+ <func>
+ <name>open(ChannelPid, File, Mode) -></name>
<name>open(ChannelPid, File, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Open a file and return a handle</fsummary>
+ <fsummary>Opens a file and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>File = string()</v>
@@ -175,14 +256,14 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a file on the server, and returns a handle that
+ <p>Opens a file on the server and returns a handle, which
can be used for reading or writing.</p>
</desc>
</func>
<func>
- <name>opendir(ChannelPid, Path) -> </name>
+ <name>opendir(ChannelPid, Path) -></name>
<name>opendir(ChannelPid, Path, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Open a directory and return a handle</fsummary>
+ <fsummary>Opens a directory and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
@@ -190,7 +271,7 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a handle to a directory on the server, the handle
+ <p>Opens a handle to a directory on the server. The handle
can be used for reading directory contents.</p>
</desc>
</func>
@@ -198,14 +279,15 @@
<func>
<name>open_tar(ChannelPid, Path, Mode) -></name>
<name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, Reason}</name>
- <fsummary>Opens a tar file on the server to which <v>ChannelPid</v> is connected and returns a handle</fsummary>
+ <fsummary>Opens a tar file on the server to which <c>ChannelPid</c>
+ is connected and returns a handle.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Path = string()</v>
- <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt] </v>
+ <v>Mode = [read] | [write] | [read,EncryptOpt] | [write,DecryptOpt]</v>
<v>EncryptOpt = {crypto,{InitFun,EncryptFun,CloseFun}}</v>
<v>DecryptOpt = {crypto,{InitFun,DecryptFun}}</v>
- <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize}) </v>
+ <v>InitFun = (fun() -> {ok,CryptoState}) | (fun() -> {ok,CryptoState,ChunkSize})</v>
<v>CryptoState = any()</v>
<v>ChunkSize = undefined | pos_integer()</v>
<v>EncryptFun = (fun(PlainBin,CryptoState) -> EncryptResult)</v>
@@ -219,113 +301,86 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Opens a handle to a tar file on the server associated with <c>ChannelPid</c>. The handle
- can be used for remote tar creation and extraction as defined by the
- <seealso marker="stdlib:erl_tar#init/3">erl_tar:init/3</seealso> function.
+ <p>Opens a handle to a tar file on the server, associated with <c>ChannelPid</c>.
+ The handle can be used for remote tar creation and extraction, as defined by the
+ <seealso marker="stdlib:erl_tar#init-3">erl_tar:init/3</seealso> function.
</p>
- <p>An example of writing and then reading a tar file:</p>
- <code type="none">
- {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:add(HandleWrite, .... ),
- ...
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:close(HandleWrite),
-
- %% And for reading
- {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
- {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
- ok = erl_tar:close(HandleRead),
- </code>
-
- <p>The <c>crypto</c> mode option is applied to the generated stream of bytes just prior to sending
- them to the sftp server. This is intended for encryption but could of course be used for other
+
+ <p> For code exampel see Section
+ <seealso marker="using_ssh">SFTP Client with TAR Compression and Encryption</seealso> in
+ the ssh Users Guide. </p>
+
+ <p>The <c>crypto</c> mode option is applied to the generated stream of bytes prior to sending
+ them to the SFTP server. This is intended for encryption but can be used for other
purposes.
</p>
<p>The <c>InitFun</c> is applied once
- prior to any other crypto operation. The returned <c>CryptoState</c> is then folded into
- repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned
- from those Funs are sent further to the remote sftp server. Finally - if doing encryption
- - the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is
+ prior to any other <c>crypto</c> operation. The returned <c>CryptoState</c> is then folded into
+ repeated applications of the <c>EncryptFun</c> or <c>DecryptFun</c>. The binary returned
+ from those funs are sent further to the remote SFTP server. Finally, if doing encryption,
+ the <c>CloseFun</c> is applied to the last piece of data. The <c>CloseFun</c> is
responsible for padding (if needed) and encryption of that last piece.
</p>
<p>The <c>ChunkSize</c> defines the size of the <c>PlainBin</c>s that <c>EncodeFun</c> is applied
- to. If the <c>ChunkSize</c> is <c>undefined</c> the size of the <c>PlainBin</c>s varies because
- this is inteded for stream crypto while a fixed <c>ChunkSize</c> is intended for block crypto. It
- is possible to change the <c>ChunkSize</c>s in the return from the <c>EncryptFun</c> or
- <c>DecryptFun</c>. It is in fact possible to change the value between <c>pos_integer()</c> and
- <c>undefined</c>.
+ to. If the <c>ChunkSize</c> is <c>undefined</c>, the size of the <c>PlainBin</c>s varies,
+ because this is intended for stream crypto, whereas a fixed <c>ChunkSize</c> is intended for block crypto.
+ <c>ChunkSize</c>s can be changed in the return from the <c>EncryptFun</c> or
+ <c>DecryptFun</c>. The value can be changed between <c>pos_integer()</c> and <c>undefined</c>.
</p>
- <p>The write and read example above can be extended with encryption and decryption:</p>
- <code type="none">
- %% First three parameters depending on which crypto type we select:
- Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
- Ivec0 = crypto:rand_bytes(16),
- DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
-
- %% Initialization of the CryptoState, in this case it is the Ivector.
- InitFun = fun() -> {ok, Ivec0, DataSize} end,
-
- %% How to encrypt:
- EncryptFun =
- fun(PlainBin,Ivec) ->
- EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
- {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
- end,
-
- %% What to do with the very last block:
- CloseFun =
- fun(PlainBin, Ivec) ->
- EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
- pad(16,PlainBin) %% Last chunk
- ),
- {ok, EncryptedBin}
- end,
-
- Cw = {InitFun,EncryptFun,CloseFun},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:add(HandleWrite, .... ),
- ...
- ok = erl_tar:add(HandleWrite, .... ),
- ok = erl_tar:close(HandleWrite),
-
- %% And for decryption (in this crypto example we could use the same InitFun
- %% as for encryption):
- DecryptFun =
- fun(EncryptedBin,Ivec) ->
- PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
- {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
- end,
-
- Cr = {InitFun,DecryptFun},
- {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
- {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
- ok = erl_tar:close(HandleRead),
- </code>
+
</desc>
</func>
<func>
- <name>close(ChannelPid, Handle) -> </name>
- <name>close(ChannelPid, Handle, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Close an open handle</fsummary>
+ <name>position(ChannelPid, Handle, Location) -></name>
+ <name>position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition | {error, Error}</name>
+ <fsummary>Sets the file position of a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
+ <v>Location = Offset
+ | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v>
+ <v>Offset = integer()</v>
<v>Timeout = timeout()</v>
+ <v>NewPosition = integer()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Closes a handle to an open file or directory on the server.</p>
+ <p>Sets the file position of the file referenced by <c><![CDATA[Handle]]></c>.
+ Returns <c><![CDATA[{ok, NewPosition}]]></c> (as an absolute offset) if
+ successful, otherwise <c><![CDATA[{error, Reason}]]></c>. <c><![CDATA[Location]]></c> is
+ one of the following:</p>
+ <taglist>
+ <tag><c><![CDATA[Offset]]></c></tag>
+ <item>
+ <p>The same as <c><![CDATA[{bof, Offset}]]></c>.</p>
+ </item>
+ <tag><c><![CDATA[{bof, Offset}]]></c></tag>
+ <item>
+ <p>Absolute offset.</p>
+ </item>
+ <tag><c><![CDATA[{cur, Offset}]]></c></tag>
+ <item>
+ <p>Offset from the current position.</p>
+ </item>
+ <tag><c><![CDATA[{eof, Offset}]]></c></tag>
+ <item>
+ <p>Offset from the end of file.</p>
+ </item>
+ <tag><c><![CDATA[bof | cur | eof]]></c></tag>
+ <item>
+ <p>The same as eariler with <c><![CDATA[Offset]]></c> 0,
+ that is, <c><![CDATA[{bof, 0} | {cur, 0} | {eof, 0}]]></c>.
+ </p>
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
- <name>read(ChannelPid, Handle, Len) -> </name>
- <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
- <name>pread(ChannelPid, Handle, Position, Len) -> </name>
+ <name>pread(ChannelPid, Handle, Position, Len) -></name>
<name>pread(ChannelPid, Handle, Position, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
- <fsummary>Read from an open file</fsummary>
+ <fsummary>Reads from an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
@@ -336,47 +391,16 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Reads <c><![CDATA[Len]]></c> bytes from the file referenced by
- <c><![CDATA[Handle]]></c>. Returns <c><![CDATA[{ok, Data}]]></c>, <c><![CDATA[eof]]></c>, or
- <c><![CDATA[{error, Reason}]]></c>. If the file is opened with <c><![CDATA[binary]]></c>,
- <c><![CDATA[Data]]></c> is a binary, otherwise it is a string.</p>
- <p>If the file is read past eof, only the remaining bytes
- will be read and returned. If no bytes are read, <c><![CDATA[eof]]></c>
- is returned.</p>
- <p>The <c><![CDATA[pread]]></c> function reads from a specified position,
- combining the <c><![CDATA[position]]></c> and <c><![CDATA[read]]></c> functions.</p>
- </desc>
- </func>
- <func>
- <name>aread(ChannelPid, Handle, Len) -> {async, N} | {error, Error}</name>
- <name>apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, Error}</name>
- <fsummary>Read asynchronously from an open file</fsummary>
- <type>
- <v>ChannelPid = pid()</v>
- <v>Handle = term()</v>
- <v>Position = integer()</v>
- <v>Len = integer()</v>
- <v>N = term()</v>
- <v>Reason = term()</v>
- </type>
- <desc>
- <p>Reads from an open file, without waiting for the result. If the
- handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where N
- is a term guaranteed to be unique between calls of <c><![CDATA[aread]]></c>.
- The actual data is sent as a message to the calling process. This
- message has the form <c><![CDATA[{async_reply, N, Result}]]></c>, where
- <c><![CDATA[Result]]></c> is the result from the read, either <c><![CDATA[{ok, Data}]]></c>,
- or <c><![CDATA[eof]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
- <p>The <c><![CDATA[apread]]></c> function reads from a specified position,
- combining the <c><![CDATA[position]]></c> and <c><![CDATA[aread]]></c> functions.</p>
+ <p>The <c><![CDATA[pread]]></c> function reads from a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[read]]></c> functions.</p>
+ <p><seealso marker="#read-4">ssh_sftp:read/4</seealso></p>
</desc>
</func>
+
<func>
- <name>write(ChannelPid, Handle, Data) -></name>
- <name>write(ChannelPid, Handle, Data, Timeout) -> ok | {error, Error}</name>
- <name>pwrite(ChannelPid, Handle, Position, Data) -> ok </name>
+ <name>pwrite(ChannelPid, Handle, Position, Data) -> ok</name>
<name>pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, Error}</name>
- <fsummary>Write to an open file</fsummary>
+ <fsummary>Writes to an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
@@ -386,94 +410,59 @@
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes<c><![CDATA[data]]></c> to the file referenced by <c><![CDATA[Handle]]></c>.
- The file should be opened with <c><![CDATA[write]]></c> or <c><![CDATA[append]]></c>
- flag. Returns <c><![CDATA[ok]]></c> if successful or S<c><![CDATA[{error, Reason}]]></c>
- otherwise.</p>
- <p>Typical error reasons are:</p>
- <taglist>
- <tag><c><![CDATA[ebadf]]></c></tag>
- <item>
- <p>The file is not opened for writing.</p>
- </item>
- <tag><c><![CDATA[enospc]]></c></tag>
- <item>
- <p>There is a no space left on the device.</p>
- </item>
- </taglist>
+ <p>The <c><![CDATA[pread]]></c> function writes to a specified position,
+ combining the <c><![CDATA[position]]></c> and <c><![CDATA[write]]></c> functions.</p>
+ <p><seealso marker="#write-3">ssh_sftp:write/3</seealso></p>
</desc>
</func>
- <func>
- <name>awrite(ChannelPid, Handle, Data) -> ok | {error, Reason} </name>
- <name>apwrite(ChannelPid, Handle, Position, Data) -> ok | {error, Reason}</name>
- <fsummary>Write asynchronously to an open file</fsummary>
+
+
+ <func>
+ <name>read(ChannelPid, Handle, Len) -></name>
+ <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, Error}</name>
+ <fsummary>Reads from an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
<v>Position = integer()</v>
<v>Len = integer()</v>
- <v>Data = binary()</v>
<v>Timeout = timeout()</v>
+ <v>Data = string() | binary()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes to an open file, without waiting for the result. If the
- handle is valid, the function returns <c><![CDATA[{async, N}]]></c>, where N
- is a term guaranteed to be unique between calls of
- <c><![CDATA[awrite]]></c>. The result of the <c><![CDATA[write]]></c> operation is sent
- as a message to the calling process. This message has the form
- <c><![CDATA[{async_reply, N, Result}]]></c>, where <c><![CDATA[Result]]></c> is the result
- from the write, either <c><![CDATA[ok]]></c>, or <c><![CDATA[{error, Error}]]></c>.</p>
- <p>The <c><![CDATA[apwrite]]></c> writes on a specified position, combining
- the <c><![CDATA[position]]></c> and <c><![CDATA[awrite]]></c> operations.</p>
+ <p>Reads <c><![CDATA[Len]]></c> bytes from the file referenced by
+ <c><![CDATA[Handle]]></c>. Returns <c><![CDATA[{ok, Data}]]></c>, <c><![CDATA[eof]]></c>, or
+ <c><![CDATA[{error, Reason}]]></c>. If the file is opened with <c><![CDATA[binary]]></c>,
+ <c><![CDATA[Data]]></c> is a binary, otherwise it is a string.</p>
+ <p>If the file is read past <c>eof</c>, only the remaining bytes
+ are read and returned. If no bytes are read, <c><![CDATA[eof]]></c>
+ is returned.</p>
</desc>
</func>
- <func>
- <name>position(ChannelPid, Handle, Location) -> </name>
- <name>position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition | {error, Error}</name>
- <fsummary>Seek position in open file</fsummary>
+
+ <func>
+ <name>read_file(ChannelPid, File) -></name>
+ <name>read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, Reason}</name>
+ <fsummary>Reads a file.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>Handle = term()</v>
- <v>Location = Offset | {bof, Offset} | {cur, Offset} | {eof, Offset} | bof | cur | eof</v>
- <v>Offset = integer()</v>
+ <v>ChannelPid = pid()</v>
+ <v>File = string()</v>
+ <v>Data = binary()</v>
<v>Timeout = timeout()</v>
- <v>NewPosition = integer()</v>
- <v>Reason = term()</v>
+ <v>Reason = term()</v>
</type>
<desc>
- <p>Sets the file position of the file referenced by <c><![CDATA[Handle]]></c>.
- Returns <c><![CDATA[{ok, NewPosition}]]></c> (as an absolute offset) if
- successful, otherwise <c><![CDATA[{error, Reason}]]></c>. <c><![CDATA[Location]]></c> is
- one of the following:</p>
- <taglist>
- <tag><c><![CDATA[Offset]]></c></tag>
- <item>
- <p>The same as <c><![CDATA[{bof, Offset}]]></c>.</p>
- </item>
- <tag><c><![CDATA[{bof, Offset}]]></c></tag>
- <item>
- <p>Absolute offset.</p>
- </item>
- <tag><c><![CDATA[{cur, Offset}]]></c></tag>
- <item>
- <p>Offset from the current position.</p>
- </item>
- <tag><c><![CDATA[{eof, Offset}]]></c></tag>
- <item>
- <p>Offset from the end of file.</p>
- </item>
- <tag><c><![CDATA[bof | cur | eof]]></c></tag>
- <item>
- <p>The same as above with <c><![CDATA[Offset]]></c> 0.</p>
- </item>
- </taglist>
+ <p>Reads a file from the server, and returns the data in a binary,
+ like
+ <seealso marker="kernel:file#read_file-1">file:read_file/1</seealso></p>
</desc>
</func>
- <func>
- <name>read_file_info(ChannelPid, Name) -> </name>
+
+ <func>
+ <name>read_file_info(ChannelPid, Name) -></name>
<name>read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
- <fsummary>Get information about a file</fsummary>
+ <fsummary>Gets information about a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
@@ -484,138 +473,191 @@
</type>
<desc>
<p>Returns a <c><![CDATA[file_info]]></c> record from the file specified by
- <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>, like <c><![CDATA[file:read_file_info/2]]></c>.</p>
+ <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>,
+ like <seealso marker="kernel:file#read_file_info-2">file:read_file_info/2</seealso></p>
</desc>
</func>
- <func>
- <name>read_link_info(ChannelPid, Name) -> {ok, FileInfo} | {error, Reason}</name>
- <name>read_link_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
- <fsummary>Get information about a symbolic link</fsummary>
+
+ <func>
+ <name>read_link(ChannelPid, Name) -></name>
+ <name>read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, Reason}</name>
+ <fsummary>Reads symbolic link.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
- <v>Handle = term()</v>
- <v>Timeout = timeout()</v>
- <v>FileInfo = record()</v>
+ <v>Target = string()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Returns a <c><![CDATA[file_info]]></c> record from the symbolic
- link specified by <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>, like
- <c><![CDATA[file:read_link_info/2]]></c>.</p>
+ <p>Reads the link target from the symbolic link specified
+ by <c><![CDATA[name]]></c>, like
+ <seealso marker="kernel:file#read_link-1">file:read_link/1</seealso></p>
</desc>
</func>
- <func>
- <name>write_file_info(ChannelPid, Name, Info) -> </name>
- <name>write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Write information for a file</fsummary>
+
+ <func>
+ <name>read_link_info(ChannelPid, Name) -> {ok, FileInfo} | {error, Reason}</name>
+ <name>read_link_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, Reason}</name>
+ <fsummary>Gets information about a symbolic link.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
- <v>Info = record()</v>
+ <v>Handle = term()</v>
<v>Timeout = timeout()</v>
+ <v>FileInfo = record()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Writes file information from a <c><![CDATA[file_info]]></c> record to the
- file specified by <c><![CDATA[Name]]></c>, like <c><![CDATA[file:write_file_info]]></c>.</p>
+ <p>Returns a <c><![CDATA[file_info]]></c> record from the symbolic
+ link specified by <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>, like
+ <seealso marker="kernel:file#read_link_info-2">file:read_link_info/2</seealso></p>
</desc>
</func>
+
<func>
- <name>read_link(ChannelPid, Name) -> </name>
- <name>read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, Reason}</name>
- <fsummary>Read symbolic link</fsummary>
+ <name>rename(ChannelPid, OldName, NewName) -> </name>
+ <name>rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Renames a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
- <v>Target = string()</v>
+ <v>OldName = string()</v>
+ <v>NewName = string()</v>
+ <v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Reads the link target from the symbolic link specified
- by <c><![CDATA[name]]></c>, like <c><![CDATA[file:read_link/1]]></c>.</p>
+ <p>Renames a file named <c><![CDATA[OldName]]></c> and gives it the name
+ <c><![CDATA[NewName]]></c>, like
+ <seealso marker="kernel:file#rename-2">file:rename/2</seealso></p>
</desc>
</func>
+
<func>
- <name>make_symlink(ChannelPid, Name, Target) -> </name>
- <name>make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Create symbolic link</fsummary>
+ <name>start_channel(ConnectionRef) -></name>
+ <name>start_channel(ConnectionRef, Options) -></name>
+ <name>start_channel(Host, Options) -></name>
+ <name>start_channel(Host, Port, Options) -> {ok, Pid} | {ok, Pid, ConnectionRef} |
+ {error, Reason}</name>
+ <fsummary>Starts an SFTP client.</fsummary>
<type>
- <v>ChannelPid = pid()</v>
- <v>Name = string()</v>
- <v>Target = string()</v>
+ <v>Host = string()</v>
+ <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>Port = integer()</v>
+ <v>Options = [{Option, Value}]</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Creates a symbolic link pointing to <c><![CDATA[Target]]></c> with the
- name <c><![CDATA[Name]]></c>, like <c><![CDATA[file:make_symlink/2]]></c>.</p>
+ <p>If no connection reference is provided, a connection is set
+ up, and the new connection is returned. An SSH channel process
+ is started to handle the communication with the SFTP server.
+ The returned <c>pid</c> for this process is to be used as input to
+ all other API functions in this module.</p>
+
+ <p>Options:</p>
+ <taglist>
+ <tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
+ <item>
+ <p>The time-out is passed to the <c>ssh_channel</c> start function,
+ and defaults to <c>infinity</c>.</p>
+ </item>
+ <tag>
+ <c><![CDATA[{sftp_vsn, integer()}]]></c>
+ </tag>
+ <item>
+ <p>
+ Desired SFTP protocol version.
+ The actual version is the minimum of
+ the desired version and the maximum supported
+ versions by the SFTP server.
+ </p>
+ </item>
+ </taglist>
+ <p>All other options are directly passed to
+ <seealso marker="ssh">ssh:connect/3</seealso> or ignored if a
+ connection is already provided.</p>
</desc>
</func>
- <func>
- <name>rename(ChannelPid, OldName, NewName) -> </name>
- <name>rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Rename a file</fsummary>
+
+ <func>
+ <name>stop_channel(ChannelPid) -> ok</name>
+ <fsummary>Stops the SFTP client channel.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>OldName = string()</v>
- <v>NewName = string()</v>
- <v>Timeout = timeout()</v>
- <v>Reason = term()</v>
</type>
<desc>
- <p>Renames a file named <c><![CDATA[OldName]]></c>, and gives it the name
- <c><![CDATA[NewName]]></c>, like <c><![CDATA[file:rename/2]]></c></p>
+ <p>Stops an SFTP channel. Does not close the SSH connection.
+ Use <seealso marker="ssh#close-1">ssh:close/1</seealso> to close it.</p>
</desc>
</func>
+
<func>
- <name>delete(ChannelPid, Name) -> </name>
- <name>delete(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Delete a file</fsummary>
+ <name>write(ChannelPid, Handle, Data) -></name>
+ <name>write(ChannelPid, Handle, Data, Timeout) -> ok | {error, Error}</name>
+ <fsummary>Writes to an open file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
+ <v>Handle = term()</v>
+ <v>Position = integer()</v>
+ <v>Data = iolist()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Deletes the file specified by <c><![CDATA[Name]]></c>, like
- <c><![CDATA[file:delete/1]]></c></p>
+ <p>Writes <c><![CDATA[data]]></c> to the file referenced by <c><![CDATA[Handle]]></c>.
+ The file is to be opened with <c><![CDATA[write]]></c> or <c><![CDATA[append]]></c>
+ flag. Returns <c><![CDATA[ok]]></c> if successful or <c><![CDATA[{error, Reason}]]></c>
+ otherwise.</p>
+ <p>Typical error reasons:</p>
+ <taglist>
+ <tag><c><![CDATA[ebadf]]></c></tag>
+ <item>
+ <p>File is not opened for writing.</p>
+ </item>
+ <tag><c><![CDATA[enospc]]></c></tag>
+ <item>
+ <p>No space is left on the device.</p>
+ </item>
+ </taglist>
</desc>
</func>
+
<func>
- <name>make_dir(ChannelPid, Name) -> </name>
- <name>make_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Create a directory</fsummary>
+ <name>write_file(ChannelPid, File, Iolist) -></name>
+ <name>write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
- <v>Name = string()</v>
+ <v>File = string()</v>
+ <v>Iolist = iolist()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Creates a directory specified by <c><![CDATA[Name]]></c>. <c><![CDATA[Name]]></c> should
- be a full path to a new directory. The directory can only be
- created in an existing directory.</p>
+ <p>Writes a file to the server, like <seealso
+ marker="kernel:file#write_file-2">file:write_file/2</seealso> The
+ file is created if it does not exist. The file is overwritten
+ if it exists.</p>
</desc>
</func>
+
<func>
- <name>del_dir(ChannelPid, Name) -> </name>
- <name>del_dir(ChannelPid, Name, Timeout) -> ok | {error, Reason}</name>
- <fsummary>Delete an empty directory</fsummary>
+ <name>write_file_info(ChannelPid, Name, Info) -></name>
+ <name>write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, Reason}</name>
+ <fsummary>Writes information for a file.</fsummary>
<type>
<v>ChannelPid = pid()</v>
<v>Name = string()</v>
+ <v>Info = record()</v>
<v>Timeout = timeout()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Deletes a directory specified by <c><![CDATA[Name]]></c>.
- Note that the directory must be empty before it can be successfully deleted
- </p>
+ <p>Writes file information from a <c><![CDATA[file_info]]></c> record to the
+ file specified by <c><![CDATA[Name]]></c>, like
+ <seealso marker="kernel:file#write_file_info-2">file:write_file_info/[2,3]</seealso></p>
</desc>
</func>
-
</funcs>
-
+
</erlref>
diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml
index 81c2acc575..cf50fb1b23 100644
--- a/lib/ssh/doc/src/ssh_sftpd.xml
+++ b/lib/ssh/doc/src/ssh_sftpd.xml
@@ -8,81 +8,88 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>ssh_sftpd</title>
+ <prepared></prepared>
+ <docno></docno>
<date>2005-09-22</date>
+ <rev></rev>
<file>ssh_sftpd.sgml</file>
</header>
<module>ssh_sftpd</module>
- <modulesummary>Specifies the channel process to handle an sftp subsystem.</modulesummary>
+ <modulesummary>Specifies the channel process to handle an SFTP subsystem.</modulesummary>
<description>
- <p>Specifies a channel process to handle a sftp subsystem.</p>
+ <p>Specifies a channel process to handle an SFTP subsystem.</p>
</description>
<section>
- <title>DATA TYPES </title>
- <p><c>subsystem_spec() = {subsystem_name(), {channel_callback(), channel_init_args()}} </c></p>
- <p><c>subsystem_name() = "sftp"</c></p>
- <p><c>channel_callback() = atom()</c> - Name of the erlang module implementing the
- subsystem using the ssh_channel behavior see
- <seealso marker="ssh_channel">ssh_channel(3)</seealso></p>
- <p><c> channel_init_args() = list() - The one given as argument to function
- subsystem_spec/1.</c></p>
+ <title>DATA TYPES</title>
+ <taglist>
+ <tag><c>subsystem_spec() =</c></tag>
+ <item><p><c>{subsystem_name(), {channel_callback(), channel_init_args()}}</c></p></item>
+ <tag><c>subsystem_name() =</c></tag>
+ <item><p><c>"sftp"</c></p></item>
+ <tag><c>channel_callback() =</c></tag>
+ <item><p><c>atom()</c> - Name of the Erlang module implementing the subsystem using the
+ <c>ssh_channel</c> behavior, see the
+ <seealso marker="ssh_channel">ssh_channel(3)</seealso> manual page.</p></item>
+ <tag><c>channel_init_args() =</c></tag>
+ <item><p><c>list()</c> - The one given as argument to function <c>subsystem_spec/1</c>.</p></item>
+ </taglist>
</section>
<funcs>
<func>
<name>subsystem_spec(Options) -> subsystem_spec()</name>
- <fsummary>Returns the subsystem specification that allows an ssh daemon to handle the subsystem "sftp".</fsummary>
+ <fsummary>Returns the subsystem specification that allows an SSH daemon to handle the subsystem "sftp".</fsummary>
<type>
<v>Options = [{Option, Value}]</v>
</type>
<desc>
- <p>Should be used together with ssh:daemon/[1,2,3]</p>
- <p>Options are:</p>
+ <p>Is to be used together with <c>ssh:daemon/[1,2,3]</c></p>
+ <p>Options:</p>
<taglist>
<tag><c><![CDATA[{cwd, String}]]></c></tag>
<item>
- <p>Sets the initial current working directory for the
- server.</p>
+ <p>Sets the initial current working directory for the server.</p>
</item>
<tag><c><![CDATA[{file_handler, CallbackModule}]]></c></tag>
<item>
<p>Determines which module to call for accessing
- the file server. The default value is <c>ssh_sftpd_file</c> that uses the
- <seealso marker="kernel:file">file</seealso> and <seealso marker="stdlib:filelib">filelib</seealso> API:s to access the standard OTP file
- server. This option may be used to plug in
+ the file server. The default value is <c>ssh_sftpd_file</c>, which uses the
+ <seealso marker="kernel:file">file</seealso> and <seealso marker="stdlib:filelib">filelib</seealso>
+ APIs to access the standard OTP file server. This option can be used to plug in
other file servers.</p>
</item>
<tag><c><![CDATA[{max_files, Integer}]]></c></tag>
<item>
<p>The default value is <c>0</c>, which means that there is no upper limit.
- If supplied, the number of filenames returned to the sftp client per <c>READDIR</c>
+ If supplied, the number of filenames returned to the SFTP client per <c>READDIR</c>
request is limited to at most the given value.</p>
</item>
<tag><c><![CDATA[{root, String}]]></c></tag>
<item>
- <p>Sets the sftp root directory. The user will then not be
- able to see any files above this root. If for instance
- the root is set to <c>/tmp</c> the user will see this
- directory as <c>/</c> and if the user does cd <c>/etc</c>
- the user will end up in <c>/tmp/etc</c>.
+ <p>Sets the SFTP root directory. Then the user cannot see any files
+ above this root. If, for example, the root directory is set to <c>/tmp</c>,
+ then the user sees this directory as <c>/</c>. If the user then writes
+ <c>cd /etc</c>, the user moves to <c>/tmp/etc</c>.
</p>
</item>
<tag><c><![CDATA[{sftpd_vsn, integer()}]]></c></tag>
<item>
- <p>Sets the sftp version to use, defaults to 5. Version 6 is under
+ <p>Sets the SFTP version to use. Defaults to 5. Version 6 is under
development and limited.</p>
</item>
</taglist>
diff --git a/lib/ssh/doc/src/usersguide.xml b/lib/ssh/doc/src/usersguide.xml
index 8ab14c2945..7c925a3762 100644
--- a/lib/ssh/doc/src/usersguide.xml
+++ b/lib/ssh/doc/src/usersguide.xml
@@ -8,30 +8,32 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
+ 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
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
<title>SSH User's Guide</title>
<prepared>OTP Team</prepared>
+ <docno></docno>
<date>2012-10-11</date>
+ <rev></rev>
<file>usersguide.xml</file>
</header>
<description>
- <p>The <em>SSH</em> application implements the SSH (Secure Shell) protocol and
- provides an SFTP (Secret File Transfer Protocol) client and server.
+ <p>The Erlang Secure Shell (SSH) application, <c>ssh</c>, implements the SSH Transport Layer Protocol and
+ provides SSH File Transfer Protocol (SFTP) clients and servers.
</p>
</description>
<xi:include href="introduction.xml"/>
- <xi:include href="ssh_protocol.xml"/>
<xi:include href="using_ssh.xml"/>
</part>
diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml
index 46178d4018..6826f20fb3 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -9,77 +9,84 @@
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
+ 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.
</legalnotice>
- <title>Getting started</title>
+ <title>Getting Started</title>
+ <prepared></prepared>
+ <docno></docno>
+ <approved></approved>
+ <date></date>
+ <rev></rev>
<file>using_ssh.xml</file>
</header>
<section>
- <title> General information</title>
- <p>The examples in the following sections use the utility function
- <seealso marker="ssh#start-0"> ssh:start/0 </seealso> that starts
- all needed applications (crypto, public_key and ssh). All examples
- are run in an Erlang shell, or in a bash shell using openssh to
- illustrate how the erlang ssh application can be used. The
- examples are run as the user otptest on a local network where the
- user is authorized to login in over ssh to the host "tarlop". If
- nothing else is stated it is persumed that the otptest user has an
- entry in tarlop's authorized_keys file (may log in via ssh without
- entering a password). Also tarlop is a known host in the user
- otptest's known_hosts file so that host verification can be done
- without user interaction.
+ <title>General Information</title>
+ <p>The following examples use the utility function
+ <seealso marker="ssh#start-0"> ssh:start/0</seealso> to start
+ all needed applications (<c>crypto</c>, <c>public_key</c>, and <c>ssh</c>).
+ All examples are run in an Erlang shell, or in a bash shell, using <em>openssh</em>
+ to illustrate how the <c>ssh</c> application can be used. The
+ examples are run as the user <c>otptest</c> on a local network where the
+ user is authorized to log in over <c>ssh</c> to the host <em>tarlop</em>.
+ </p>
+ <p>If nothing else is stated, it is presumed that the <c>otptest</c> user
+ has an entry in the <em>authorized_keys</em> file of <em>tarlop</em>
+ (allowed to log in over <c>ssh</c> without entering a password).
+ Also, <em>tarlop</em> is a known host in the <c>known_hosts</c>
+ file of the user <c>otptest</c>. This means that host-verification
+ can be done without user-interaction.
</p>
</section>
<section>
- <title>Using the Erlang SSH Terminal Client</title>
+ <title>Using the Erlang ssh Terminal Client</title>
- <p>The user otptest, that has bash as default shell, uses the
- ssh:shell/1 client to connect to the openssh daemon running on a
- host called tarlop. Note that currently this client is very simple
- and you should not be expected to be as fancy as the openssh
- client.</p>
+ <p>The user <c>otptest</c>, which has bash as default shell, uses the
+ <c>ssh:shell/1</c> client to connect to the <em>openssh</em> daemon running on a
+ host called <em>tarlop</em>:</p>
<code type="erl" >
1> ssh:start().
ok
2> {ok, S} = ssh:shell("tarlop").
- >pwd
+ otptest@tarlop:> pwd
/home/otptest
- >exit
+ otptest@tarlop:> exit
logout
3>
</code>
</section>
<section>
- <title>Running an Erlang SSH Daemon </title>
+ <marker id="Running an Erlang ssh Daemon"></marker>
+ <title>Running an Erlang ssh Daemon</title>
- <p> The option system_dir must be a directory containing a host
- key file and it defaults to /etc/ssh. For details see section
+ <p>The <c>system_dir</c> option must be a directory containing a host
+ key file and it defaults to <c>/etc/ssh</c>. For details, see Section
Configuration Files in <seealso
marker="SSH_app">ssh(6)</seealso>.
</p>
- <note><p>Normally the /etc/ssh directory is only readable by root. </p>
+ <note><p>Normally, the <c>/etc/ssh</c> directory is only readable by root.</p>
</note>
- <p> The option user_dir defaults to the users ~/.ssh directory</p>
+ <p>The option <c>user_dir</c> defaults to directory <c>users ~/.ssh</c>.</p>
- <p>In the following example we generate new keys and host keys as
- to be able to run the example without having root privileges</p>
+ <p><em>Step 1.</em> To run the example without root privileges,
+ generate new keys and host keys:</p>
<code>
$bash> ssh-keygen -t rsa -f /tmp/ssh_daemon/ssh_host_rsa_key
@@ -88,19 +95,22 @@
[...]
</code>
- <p>Create the file /tmp/otptest_user/.ssh/authorized_keys and add the content
- of /tmp/otptest_user/.ssh/id_rsa.pub Now we can do</p>
+ <p><em>Step 2.</em> Create the file <c>/tmp/otptest_user/.ssh/authorized_keys</c>
+ and add the content of <c>/tmp/otptest_user/.ssh/id_rsa.pub</c>.</p>
+
+ <p><em>Step 3.</em> Start the Erlang <c>ssh</c> daemon:</p>
<code type="erl">
1> ssh:start().
ok
- 2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"}]).
+ 2> {ok, Sshd} = ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"}]).
{ok,&lt;0.54.0>}
3>
</code>
- <p>Use the openssh client from a shell to connect to the Erlang ssh daemon.</p>
+ <p><em>Step 4.</em> Use the <em>openssh</em> client from a shell to connect
+ to the Erlang <c>ssh</c> daemon:</p>
<code>
$bash> ssh tarlop -p 8989 -i /tmp/otptest_user/.ssh/id_rsa\
@@ -113,9 +123,12 @@
1>
</code>
- <p>There are two ways of shutting down an SSH daemon</p>
+ <p>There are two ways of shutting down an <c>ssh</c> daemon,
+ see <em>Step 5a</em> and <em>Step 5b</em>.</p>
- <p>1: Stops the listener, but leaves existing connections started by the listener up and running.</p>
+ <p><em>Step 5a.</em> Shut down the Erlang <c>ssh</c> daemon so that it
+ stops the listener but leaves existing connections, started by the listener,
+ operational:</p>
<code type="erl">
3> ssh:stop_listener(Sshd).
@@ -123,7 +136,8 @@
4>
</code>
- <p>2: Stops the listener and all connections started by the listener.</p>
+ <p><em>Step 5b.</em> Shut down the Erlang <c>ssh</c> daemon so that it
+ stops the listener and all connections started by the listener:</p>
<code type="erl">
3> ssh:stop_daemon(Sshd)
@@ -134,17 +148,18 @@
</section>
<section>
- <title>One Time Execution</title>
+ <title>One-Time Execution</title>
- <p>In the following example the Erlang shell is the client process
- that receives the channel replies. </p>
+ <p>In the following example, the Erlang shell is the client process
+ that receives the channel replies.</p>
- <note><p> If you run this example
- in your environment you may get fewer or more messages back as
- this depends on the OS and shell on the machine running the ssh
- daemon. See also <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>
+ <note><p>The number of received messages in this example depends on which OS
+ and which shell that is used on the machine running the <c>ssh</c> daemon.
+ See also <seealso marker="ssh_connection#exec-4">ssh_connection:exec/4</seealso>.
</p></note>
+ <p>Do a one-time execution of a remote command over <c>ssh</c>:</p>
+
<code type="erl" >
1> ssh:start().
ok
@@ -162,7 +177,8 @@
6>
</code>
- <p>Note only the channel is closed the connection is still up and can handle other channels</p>
+ <p>Notice that only the channel is closed. The connection is still up and can
+ handle other channels:</p>
<code type="erl" >
6> {ok, NewChannelId} = ssh_connection:session_channel(ConnectionRef, infinity).
@@ -172,19 +188,22 @@
</section>
<section>
- <title>SFTP (SSH File Transport Protocol) server</title>
+ <title>SFTP Server</title>
+
+ <p>Start the Erlang <c>ssh</c> daemon with the SFTP subsystem:</p>
<code type="erl" >
1> ssh:start().
ok
- 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"},
- {subsystems, [ssh_sftpd:subsystem_spec([{cwd, "/tmp/sftp/example"}])]}]).
+ 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"},
+ {subsystems, [ssh_sftpd:subsystem_spec([{cwd, "/tmp/sftp/example"}])
+ ]}]).
{ok,&lt;0.54.0>}
3>
</code>
- <p> Run the openssh sftp client</p>
+ <p>Run the OpenSSH SFTP client:</p>
<code type="erl">
$bash> sftp -oPort=8989 -o IdentityFile=/tmp/otptest_user/.ssh/id_rsa\
@@ -197,7 +216,9 @@
</section>
<section>
- <title>SFTP (SSH File Transport Protocol) client</title>
+ <title>SFTP Client</title>
+
+ <p>Fetch a file with the Erlang SFTP client:</p>
<code type="erl" >
1> ssh:start().
@@ -210,10 +231,77 @@
</section>
<section>
- <title>Creating a subsystem</title>
+ <title>SFTP Client with TAR Compression and Encryption</title>
+
+ <p>Example of writing and then reading a tar file follows:</p>
+ <code type="erl">
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write]),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:add(HandleWrite, .... ),
+ ...
+ ok = erl_tar:add(HandleWrite, .... ),
+ ok = erl_tar:close(HandleWrite),
+
+ %% And for reading
+ {ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read]),
+ {ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ ok = erl_tar:close(HandleRead),
+ </code>
+
+ <p>The previous write and read example can be extended with encryption and decryption as follows:</p>
+ <code type="erl">
+%% First three parameters depending on which crypto type we select:
+Key = &lt;&lt;"This is a 256 bit key. abcdefghi">>,
+Ivec0 = crypto:strong_rand_bytes(16),
+DataSize = 1024, % DataSize rem 16 = 0 for aes_cbc
+
+%% Initialization of the CryptoState, in this case it is the Ivector.
+InitFun = fun() -> {ok, Ivec0, DataSize} end,
+
+%% How to encrypt:
+EncryptFun =
+ fun(PlainBin,Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec, PlainBin),
+ {ok, EncryptedBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+%% What to do with the very last block:
+CloseFun =
+ fun(PlainBin, Ivec) ->
+ EncryptedBin = crypto:block_encrypt(aes_cbc256, Key, Ivec,
+ pad(16,PlainBin) %% Last chunk
+ ),
+ {ok, EncryptedBin}
+ end,
+
+Cw = {InitFun,EncryptFun,CloseFun},
+{ok,HandleWrite} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [write,{crypto,Cw}]),
+ok = erl_tar:add(HandleWrite, .... ),
+ok = erl_tar:add(HandleWrite, .... ),
+...
+ok = erl_tar:add(HandleWrite, .... ),
+ok = erl_tar:close(HandleWrite),
+
+%% And for decryption (in this crypto example we could use the same InitFun
+%% as for encryption):
+DecryptFun =
+ fun(EncryptedBin,Ivec) ->
+ PlainBin = crypto:block_decrypt(aes_cbc256, Key, Ivec, EncryptedBin),
+ {ok, PlainBin, crypto:next_iv(aes_cbc,EncryptedBin)}
+ end,
+
+Cr = {InitFun,DecryptFun},
+{ok,HandleRead} = ssh_sftp:open_tar(ChannelPid, ?tar_file_name, [read,{crypto,Cw}]),
+{ok,NameValueList} = erl_tar:extract(HandleRead,[memory]),
+ok = erl_tar:close(HandleRead),
+ </code>
+ </section>
+
+ <section>
+ <title>Creating a Subsystem</title>
- <p>A very small SSH subsystem that echos N bytes could be implemented like this.
- See also <seealso marker="ssh_channel"> ssh_channel(3)</seealso> </p>
+ <p>A small <c>ssh</c> subsystem that echoes N bytes can be implemented as shown
+ in the following example:</p>
<code type="erl" >
-module(ssh_echo_server).
@@ -267,14 +355,16 @@ terminate(_Reason, _State) ->
ok.
</code>
- <p>And run like this on the host tarlop with the keys generated in section 3.3</p>
+ <p>The subsystem can be run on the host <em>tarlop</em> with the generated keys,
+ as described in Section <seealso marker="#Running an Erlang ssh Daemon">
+ Running an Erlang ssh Daemon</seealso>:</p>
<code type="erl" >
1> ssh:start().
ok
- 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
- {user_dir, "/tmp/otptest_user/.ssh"}
- {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
+ 2> ssh:daemon(8989, [{system_dir, "/tmp/ssh_daemon"},
+ {user_dir, "/tmp/otptest_user/.ssh"}
+ {subsystems, [{"echo_n", {ssh_echo_server, [10]}}]}]).
{ok,&lt;0.54.0>}
3>
</code>
@@ -293,6 +383,7 @@ terminate(_Reason, _State) ->
{ssh_msg, &lt;0.57.0>, {closed, 0}}
7> {error, closed} = ssh_connection:send(ConnectionRef, ChannelId, "10", infinity).
</code>
+<p>See also <seealso marker="ssh_channel"> ssh_channel(3)</seealso>.</p>
</section>
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
deleted file mode 100644
index d766a933b4..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.2.ps
+++ /dev/null
@@ -1,3315 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:31:26 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Protocol Architecture) s
-5 613 M
-( draft-ietf-secsh-architecture-15.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the) s
-5 261 M
-( architecture of the SSH protocol, as well as the notation and) s
-5 250 M
-( terminology used in SSH protocol documents. It also discusses the SSH) s
-5 239 M
-( algorithm naming system that allows local extensions. The SSH) s
-5 228 M
-( protocol consists of three major components: The Transport Layer) s
-5 217 M
-( Protocol provides server authentication, confidentiality, and) s
-5 206 M
-( integrity with perfect forward secrecy. The User Authentication) s
-5 195 M
-( Protocol authenticates the client to the server. The Connection) s
-5 184 M
-( Protocol multiplexes the encrypted tunnel into several logical) s
-5 173 M
-( channels. Details of these protocols are described in separate) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( documents.) s
-5 668 M
-(Table of Contents) s
-5 646 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 635 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 3. Specification of Requirements . . . . . . . . . . . . . . . 3) s
-5 613 M
-( 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 602 M
-( 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 591 M
-( 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 580 M
-( 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 569 M
-( 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6) s
-5 558 M
-( 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6) s
-5 547 M
-( 4.6 Localization and Character Set Support . . . . . . . . . . . 7) s
-5 536 M
-( 5. Data Type Representations Used in the SSH Protocols . . . . 8) s
-5 525 M
-( 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 514 M
-( 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11) s
-5 492 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 481 M
-( 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12) s
-5 470 M
-( 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 459 M
-( 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 448 M
-( 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 437 M
-( 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16) s
-5 426 M
-( 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17) s
-5 415 M
-( 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19) s
-5 393 M
-( 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 382 M
-( 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20) s
-5 371 M
-( 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 360 M
-( 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 349 M
-( 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22) s
-5 327 M
-( 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23) s
-5 305 M
-( 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( Informative References . . . . . . . . . . . . . . . . . . . 25) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27) s
-5 228 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 536 M
-( services over an insecure network. It consists of three major) s
-5 525 M
-( components:) s
-5 514 M
-( o The Transport Layer Protocol [SSH-TRANS] provides server) s
-5 503 M
-( authentication, confidentiality, and integrity. It may optionally) s
-5 492 M
-( also provide compression. The transport layer will typically be) s
-5 481 M
-( run over a TCP/IP connection, but might also be used on top of any) s
-5 470 M
-( other reliable data stream.) s
-5 459 M
-( o The User Authentication Protocol [SSH-USERAUTH] authenticates the) s
-5 448 M
-( client-side user to the server. It runs over the transport layer) s
-5 437 M
-( protocol.) s
-5 426 M
-( o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted) s
-5 415 M
-( tunnel into several logical channels. It runs over the user) s
-5 404 M
-( authentication protocol.) s
-5 382 M
-( The client sends a service request once a secure transport layer) s
-5 371 M
-( connection has been established. A second service request is sent) s
-5 360 M
-( after user authentication is complete. This allows new protocols to) s
-5 349 M
-( be defined and coexist with the protocols listed above.) s
-5 327 M
-( The connection protocol provides channels that can be used for a wide) s
-5 316 M
-( range of purposes. Standard methods are provided for setting up) s
-5 305 M
-( secure interactive shell sessions and for forwarding \("tunneling"\)) s
-5 294 M
-( arbitrary TCP/IP ports and X11 connections.) s
-5 272 M
-(3. Specification of Requirements) s
-5 250 M
-( All documents related to the SSH protocols shall use the keywords) s
-5 239 M
-( "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",) s
-5 228 M
-( "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe) s
-5 217 M
-( requirements. They are to be interpreted as described in [RFC2119].) s
-5 195 M
-(4. Architecture) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(4.1 Host Keys) s
-5 668 M
-( Each server host SHOULD have a host key. Hosts MAY have multiple) s
-5 657 M
-( host keys using multiple different algorithms. Multiple hosts MAY) s
-5 646 M
-( share the same host key. If a host has keys at all, it MUST have at) s
-5 635 M
-( least one key using each REQUIRED public key algorithm \(DSS) s
-5 624 M
-( [FIPS-186]\).) s
-5 602 M
-( The server host key is used during key exchange to verify that the) s
-5 591 M
-( client is really talking to the correct server. For this to be) s
-5 580 M
-( possible, the client must have a priori knowledge of the server's) s
-5 569 M
-( public host key.) s
-5 547 M
-( Two different trust models can be used:) s
-5 536 M
-( o The client has a local database that associates each host name \(as) s
-5 525 M
-( typed by the user\) with the corresponding public host key. This) s
-5 514 M
-( method requires no centrally administered infrastructure, and no) s
-5 503 M
-( third-party coordination. The downside is that the database of) s
-5 492 M
-( name-to-key associations may become burdensome to maintain.) s
-5 481 M
-( o The host name-to-key association is certified by some trusted) s
-5 470 M
-( certification authority. The client only knows the CA root key,) s
-5 459 M
-( and can verify the validity of all host keys certified by accepted) s
-5 448 M
-( CAs.) s
-5 426 M
-( The second alternative eases the maintenance problem, since) s
-5 415 M
-( ideally only a single CA key needs to be securely stored on the) s
-5 404 M
-( client. On the other hand, each host key must be appropriately) s
-5 393 M
-( certified by a central authority before authorization is possible.) s
-5 382 M
-( Also, a lot of trust is placed on the central infrastructure.) s
-5 360 M
-( The protocol provides the option that the server name - host key) s
-5 349 M
-( association is not checked when connecting to the host for the first) s
-5 338 M
-( time. This allows communication without prior communication of host) s
-5 327 M
-( keys or certification. The connection still provides protection) s
-5 316 M
-( against passive listening; however, it becomes vulnerable to active) s
-5 305 M
-( man-in-the-middle attacks. Implementations SHOULD NOT normally allow) s
-5 294 M
-( such connections by default, as they pose a potential security) s
-5 283 M
-( problem. However, as there is no widely deployed key infrastructure) s
-5 272 M
-( available on the Internet yet, this option makes the protocol much) s
-5 261 M
-( more usable during the transition time until such an infrastructure) s
-5 250 M
-( emerges, while still providing a much higher level of security than) s
-5 239 M
-( that offered by older solutions \(e.g. telnet [RFC-854] and rlogin) s
-5 228 M
-( [RFC-1282]\).) s
-5 206 M
-( Implementations SHOULD try to make the best effort to check host) s
-5 195 M
-( keys. An example of a possible strategy is to only accept a host key) s
-5 184 M
-( without checking the first time a host is connected, save the key in) s
-5 173 M
-( a local database, and compare against that key on all future) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( connections to that host.) s
-5 668 M
-( Implementations MAY provide additional methods for verifying the) s
-5 657 M
-( correctness of host keys, e.g. a hexadecimal fingerprint derived from) s
-5 646 M
-( the SHA-1 hash of the public key. Such fingerprints can easily be) s
-5 635 M
-( verified by using telephone or other external communication channels.) s
-5 613 M
-( All implementations SHOULD provide an option to not accept host keys) s
-5 602 M
-( that cannot be verified.) s
-5 580 M
-( We believe that ease of use is critical to end-user acceptance of) s
-5 569 M
-( security solutions, and no improvement in security is gained if the) s
-5 558 M
-( new solutions are not used. Thus, providing the option not to check) s
-5 547 M
-( the server host key is believed to improve the overall security of) s
-5 536 M
-( the Internet, even though it reduces the security of the protocol in) s
-5 525 M
-( configurations where it is allowed.) s
-5 503 M
-(4.2 Extensibility) s
-5 481 M
-( We believe that the protocol will evolve over time, and some) s
-5 470 M
-( organizations will want to use their own encryption, authentication) s
-5 459 M
-( and/or key exchange methods. Central registration of all extensions) s
-5 448 M
-( is cumbersome, especially for experimental or classified features.) s
-5 437 M
-( On the other hand, having no central registration leads to conflicts) s
-5 426 M
-( in method identifiers, making interoperability difficult.) s
-5 404 M
-( We have chosen to identify algorithms, methods, formats, and) s
-5 393 M
-( extension protocols with textual names that are of a specific format.) s
-5 382 M
-( DNS names are used to create local namespaces where experimental or) s
-5 371 M
-( classified extensions can be defined without fear of conflicts with) s
-5 360 M
-( other implementations.) s
-5 338 M
-( One design goal has been to keep the base protocol as simple as) s
-5 327 M
-( possible, and to require as few algorithms as possible. However, all) s
-5 316 M
-( implementations MUST support a minimal set of algorithms to ensure) s
-5 305 M
-( interoperability \(this does not imply that the local policy on all) s
-5 294 M
-( hosts would necessary allow these algorithms\). The mandatory) s
-5 283 M
-( algorithms are specified in the relevant protocol documents.) s
-5 261 M
-( Additional algorithms, methods, formats, and extension protocols can) s
-5 250 M
-( be defined in separate drafts. See Section Algorithm Naming \(Section) s
-5 239 M
-( 6\) for more information.) s
-5 217 M
-(4.3 Policy Issues) s
-5 195 M
-( The protocol allows full negotiation of encryption, integrity, key) s
-5 184 M
-( exchange, compression, and public key algorithms and formats.) s
-5 173 M
-( Encryption, integrity, public key, and compression algorithms can be) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( different for each direction.) s
-5 668 M
-( The following policy issues SHOULD be addressed in the configuration) s
-5 657 M
-( mechanisms of each implementation:) s
-5 646 M
-( o Encryption, integrity, and compression algorithms, separately for) s
-5 635 M
-( each direction. The policy MUST specify which is the preferred) s
-5 624 M
-( algorithm \(e.g. the first algorithm listed in each category\).) s
-5 613 M
-( o Public key algorithms and key exchange method to be used for host) s
-5 602 M
-( authentication. The existence of trusted host keys for different) s
-5 591 M
-( public key algorithms also affects this choice.) s
-5 580 M
-( o The authentication methods that are to be required by the server) s
-5 569 M
-( for each user. The server's policy MAY require multiple) s
-5 558 M
-( authentication for some or all users. The required algorithms MAY) s
-5 547 M
-( depend on the location where the user is trying to log in from.) s
-5 536 M
-( o The operations that the user is allowed to perform using the) s
-5 525 M
-( connection protocol. Some issues are related to security; for) s
-5 514 M
-( example, the policy SHOULD NOT allow the server to start sessions) s
-5 503 M
-( or run commands on the client machine, and MUST NOT allow) s
-5 492 M
-( connections to the authentication agent unless forwarding such) s
-5 481 M
-( connections has been requested. Other issues, such as which TCP/) s
-5 470 M
-( IP ports can be forwarded and by whom, are clearly issues of local) s
-5 459 M
-( policy. Many of these issues may involve traversing or bypassing) s
-5 448 M
-( firewalls, and are interrelated with the local security policy.) s
-5 426 M
-(4.4 Security Properties) s
-5 404 M
-( The primary goal of the SSH protocol is improved security on the) s
-5 393 M
-( Internet. It attempts to do this in a way that is easy to deploy,) s
-5 382 M
-( even at the cost of absolute security.) s
-5 371 M
-( o All encryption, integrity, and public key algorithms used are) s
-5 360 M
-( well-known, well-established algorithms.) s
-5 349 M
-( o All algorithms are used with cryptographically sound key sizes) s
-5 338 M
-( that are believed to provide protection against even the strongest) s
-5 327 M
-( cryptanalytic attacks for decades.) s
-5 316 M
-( o All algorithms are negotiated, and in case some algorithm is) s
-5 305 M
-( broken, it is easy to switch to some other algorithm without) s
-5 294 M
-( modifying the base protocol.) s
-5 272 M
-( Specific concessions were made to make wide-spread fast deployment) s
-5 261 M
-( easier. The particular case where this comes up is verifying that) s
-5 250 M
-( the server host key really belongs to the desired host; the protocol) s
-5 239 M
-( allows the verification to be left out \(but this is NOT RECOMMENDED\).) s
-5 228 M
-( This is believed to significantly improve usability in the short) s
-5 217 M
-( term, until widespread Internet public key infrastructures emerge.) s
-5 195 M
-(4.5 Packet Size and Overhead) s
-5 173 M
-( Some readers will worry about the increase in packet size due to new) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( headers, padding, and MAC. The minimum packet size is in the order) s
-5 679 M
-( of 28 bytes \(depending on negotiated algorithms\). The increase is) s
-5 668 M
-( negligible for large packets, but very significant for one-byte) s
-5 657 M
-( packets \(telnet-type sessions\). There are, however, several factors) s
-5 646 M
-( that make this a non-issue in almost all cases:) s
-5 635 M
-( o The minimum size of a TCP/IP header is 32 bytes. Thus, the) s
-5 624 M
-( increase is actually from 33 to 51 bytes \(roughly\).) s
-5 613 M
-( o The minimum size of the data field of an Ethernet packet is 46) s
-5 602 M
-( bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When) s
-5 591 M
-( Ethernet headers are considered, the increase is less than 10) s
-5 580 M
-( percent.) s
-5 569 M
-( o The total fraction of telnet-type data in the Internet is) s
-5 558 M
-( negligible, even with increased packet sizes.) s
-5 536 M
-( The only environment where the packet size increase is likely to have) s
-5 525 M
-( a significant effect is PPP [RFC-1134] over slow modem lines \(PPP) s
-5 514 M
-( compresses the TCP/IP headers, emphasizing the increase in packet) s
-5 503 M
-( size\). However, with modern modems, the time needed to transfer is in) s
-5 492 M
-( the order of 2 milliseconds, which is a lot faster than people can) s
-5 481 M
-( type.) s
-5 459 M
-( There are also issues related to the maximum packet size. To) s
-5 448 M
-( minimize delays in screen updates, one does not want excessively) s
-5 437 M
-( large packets for interactive sessions. The maximum packet size is) s
-5 426 M
-( negotiated separately for each channel.) s
-5 404 M
-(4.6 Localization and Character Set Support) s
-5 382 M
-( For the most part, the SSH protocols do not directly pass text that) s
-5 371 M
-( would be displayed to the user. However, there are some places where) s
-5 360 M
-( such data might be passed. When applicable, the character set for the) s
-5 349 M
-( data MUST be explicitly specified. In most places, ISO 10646 with) s
-5 338 M
-( UTF-8 encoding is used [RFC-2279]. When applicable, a field is also) s
-5 327 M
-( provided for a language tag [RFC-3066].) s
-5 305 M
-( One big issue is the character set of the interactive session. There) s
-5 294 M
-( is no clear solution, as different applications may display data in) s
-5 283 M
-( different formats. Different types of terminal emulation may also be) s
-5 272 M
-( employed in the client, and the character set to be used is) s
-5 261 M
-( effectively determined by the terminal emulation. Thus, no place is) s
-5 250 M
-( provided for directly specifying the character set or encoding for) s
-5 239 M
-( terminal session data. However, the terminal emulation type \(e.g.) s
-5 228 M
-( "vt100"\) is transmitted to the remote site, and it implicitly) s
-5 217 M
-( specifies the character set and encoding. Applications typically use) s
-5 206 M
-( the terminal type to determine what character set they use, or the) s
-5 195 M
-( character set is determined using some external means. The terminal) s
-5 184 M
-( emulation may also allow configuring the default character set. In) s
-5 173 M
-( any case, the character set for the terminal session is considered) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( primarily a client local issue.) s
-5 668 M
-( Internal names used to identify algorithms or protocols are normally) s
-5 657 M
-( never displayed to users, and must be in US-ASCII.) s
-5 635 M
-( The client and server user names are inherently constrained by what) s
-5 624 M
-( the server is prepared to accept. They might, however, occasionally) s
-5 613 M
-( be displayed in logs, reports, etc. They MUST be encoded using ISO) s
-5 602 M
-( 10646 UTF-8, but other encodings may be required in some cases. It) s
-5 591 M
-( is up to the server to decide how to map user names to accepted user) s
-5 580 M
-( names. Straight bit-wise binary comparison is RECOMMENDED.) s
-5 558 M
-( For localization purposes, the protocol attempts to minimize the) s
-5 547 M
-( number of textual messages transmitted. When present, such messages) s
-5 536 M
-( typically relate to errors, debugging information, or some externally) s
-5 525 M
-( configured data. For data that is normally displayed, it SHOULD be) s
-5 514 M
-( possible to fetch a localized message instead of the transmitted) s
-5 503 M
-( message by using a numerical code. The remaining messages SHOULD be) s
-5 492 M
-( configurable.) s
-5 470 M
-(5. Data Type Representations Used in the SSH Protocols) s
-5 459 M
-( byte) s
-5 437 M
-( A byte represents an arbitrary 8-bit value \(octet\) [RFC-1700].) s
-5 426 M
-( Fixed length data is sometimes represented as an array of bytes,) s
-5 415 M
-( written byte[n], where n is the number of bytes in the array.) s
-5 393 M
-( boolean) s
-5 371 M
-( A boolean value is stored as a single byte. The value 0) s
-5 360 M
-( represents FALSE, and the value 1 represents TRUE. All non-zero) s
-5 349 M
-( values MUST be interpreted as TRUE; however, applications MUST NOT) s
-5 338 M
-( store values other than 0 and 1.) s
-5 316 M
-( uint32) s
-5 294 M
-( Represents a 32-bit unsigned integer. Stored as four bytes in the) s
-5 283 M
-( order of decreasing significance \(network byte order\). For) s
-5 272 M
-( example, the value 699921578 \(0x29b7f4aa\) is stored as 29 b7 f4) s
-5 261 M
-( aa.) s
-5 239 M
-( uint64) s
-5 217 M
-( Represents a 64-bit unsigned integer. Stored as eight bytes in) s
-5 206 M
-( the order of decreasing significance \(network byte order\).) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( string) s
-5 668 M
-( Arbitrary length binary string. Strings are allowed to contain) s
-5 657 M
-( arbitrary binary data, including null characters and 8-bit) s
-5 646 M
-( characters. They are stored as a uint32 containing its length) s
-5 635 M
-( \(number of bytes that follow\) and zero \(= empty string\) or more) s
-5 624 M
-( bytes that are the value of the string. Terminating null) s
-5 613 M
-( characters are not used.) s
-5 591 M
-( Strings are also used to store text. In that case, US-ASCII is) s
-5 580 M
-( used for internal names, and ISO-10646 UTF-8 for text that might) s
-5 569 M
-( be displayed to the user. The terminating null character SHOULD) s
-5 558 M
-( NOT normally be stored in the string.) s
-5 536 M
-( For example, the US-ASCII string "testing" is represented as 00 00) s
-5 525 M
-( 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding) s
-5 514 M
-( of US-ASCII characters.) s
-5 492 M
-( mpint) s
-5 470 M
-( Represents multiple precision integers in two's complement format,) s
-5 459 M
-( stored as a string, 8 bits per byte, MSB first. Negative numbers) s
-5 448 M
-( have the value 1 as the most significant bit of the first byte of) s
-5 437 M
-( the data partition. If the most significant bit would be set for a) s
-5 426 M
-( positive number, the number MUST be preceded by a zero byte.) s
-5 415 M
-( Unnecessary leading bytes with the value 0 or 255 MUST NOT be) s
-5 404 M
-( included. The value zero MUST be stored as a string with zero) s
-5 393 M
-( bytes of data.) s
-5 371 M
-( By convention, a number that is used in modular computations in) s
-5 360 M
-( Z_n SHOULD be represented in the range 0 <= x < n.) s
-5 338 M
-( Examples:) s
-5 327 M
-( value \(hex\) representation \(hex\)) s
-5 316 M
-( ---------------------------------------------------------------) s
-5 305 M
-( 0 00 00 00 00) s
-5 294 M
-( 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7) s
-5 283 M
-( 80 00 00 00 02 00 80) s
-5 272 M
-( -1234 00 00 00 02 ed cc) s
-5 261 M
-( -deadbeef 00 00 00 05 ff 21 52 41 11) s
-5 217 M
-( name-list) s
-5 195 M
-( A string containing a comma separated list of names. A name list) s
-5 184 M
-( is represented as a uint32 containing its length \(number of bytes) s
-5 173 M
-( that follow\) followed by a comma-separated list of zero or more) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( names. A name MUST be non-zero length, and it MUST NOT contain a) s
-5 679 M
-( comma \(','\). Context may impose additional restrictions on the) s
-5 668 M
-( names; for example, the names in a list may have to be valid) s
-5 657 M
-( algorithm identifier \(see Algorithm Naming below\), or [RFC-3066]) s
-5 646 M
-( language tags. The order of the names in a list may or may not be) s
-5 635 M
-( significant, also depending on the context where the list is is) s
-5 624 M
-( used. Terminating NUL characters are not used, neither for the) s
-5 613 M
-( individual names, nor for the list as a whole.) s
-5 591 M
-( Examples:) s
-5 580 M
-( value representation \(hex\)) s
-5 569 M
-( ---------------------------------------) s
-5 558 M
-( \(\), the empty list 00 00 00 00) s
-5 547 M
-( \("zlib"\) 00 00 00 04 7a 6c 69 62) s
-5 536 M
-( \("zlib", "none"\) 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65) s
-5 481 M
-(6. Algorithm Naming) s
-5 459 M
-( The SSH protocols refer to particular hash, encryption, integrity,) s
-5 448 M
-( compression, and key exchange algorithms or protocols by names.) s
-5 437 M
-( There are some standard algorithms that all implementations MUST) s
-5 426 M
-( support. There are also algorithms that are defined in the protocol) s
-5 415 M
-( specification but are OPTIONAL. Furthermore, it is expected that) s
-5 404 M
-( some organizations will want to use their own algorithms.) s
-5 382 M
-( In this protocol, all algorithm identifiers MUST be printable) s
-5 371 M
-( US-ASCII non-empty strings no longer than 64 characters. Names MUST) s
-5 360 M
-( be case-sensitive.) s
-5 338 M
-( There are two formats for algorithm names:) s
-5 327 M
-( o Names that do not contain an at-sign \(@\) are reserved to be) s
-5 316 M
-( assigned by IETF consensus \(RFCs\). Examples include `3des-cbc',) s
-5 305 M
-( `sha-1', `hmac-sha1', and `zlib' \(the quotes are not part of the) s
-5 294 M
-( name\). Names of this format MUST NOT be used without first) s
-5 283 M
-( registering them. Registered names MUST NOT contain an at-sign) s
-5 272 M
-( \(@\) or a comma \(,\).) s
-5 261 M
-( o Anyone can define additional algorithms by using names in the) s
-5 250 M
-( format name@domainname, e.g. "[email protected]". The) s
-5 239 M
-( format of the part preceding the at sign is not specified; it MUST) s
-5 228 M
-( consist of US-ASCII characters except at-sign and comma. The part) s
-5 217 M
-( following the at-sign MUST be a valid fully qualified internet) s
-5 206 M
-( domain name [RFC-1034] controlled by the person or organization) s
-5 195 M
-( defining the name. It is up to each domain how it manages its) s
-5 184 M
-( local namespace.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(7. Message Numbers) s
-5 668 M
-( SSH packets have message numbers in the range 1 to 255. These numbers) s
-5 657 M
-( have been allocated as follows:) s
-5 624 M
-( Transport layer protocol:) s
-5 602 M
-( 1 to 19 Transport layer generic \(e.g. disconnect, ignore, debug,) s
-5 591 M
-( etc.\)) s
-5 580 M
-( 20 to 29 Algorithm negotiation) s
-5 569 M
-( 30 to 49 Key exchange method specific \(numbers can be reused for) s
-5 558 M
-( different authentication methods\)) s
-5 536 M
-( User authentication protocol:) s
-5 514 M
-( 50 to 59 User authentication generic) s
-5 503 M
-( 60 to 79 User authentication method specific \(numbers can be) s
-5 492 M
-( reused for different authentication methods\)) s
-5 470 M
-( Connection protocol:) s
-5 448 M
-( 80 to 89 Connection protocol generic) s
-5 437 M
-( 90 to 127 Channel related messages) s
-5 415 M
-( Reserved for client protocols:) s
-5 393 M
-( 128 to 191 Reserved) s
-5 371 M
-( Local extensions:) s
-5 349 M
-( 192 to 255 Local extensions) s
-5 305 M
-(8. IANA Considerations) s
-5 283 M
-( The initial state of the IANA registry is detailed in [SSH-NUMBERS].) s
-5 261 M
-( Allocation of the following types of names in the SSH protocols is) s
-5 250 M
-( assigned by IETF consensus:) s
-5 239 M
-( o SSH encryption algorithm names,) s
-5 228 M
-( o SSH MAC algorithm names,) s
-5 217 M
-( o SSH public key algorithm names \(public key algorithm also implies) s
-5 206 M
-( encoding and signature/encryption capability\),) s
-5 195 M
-( o SSH key exchange method names, and) s
-5 184 M
-( o SSH protocol \(service\) names.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( These names MUST be printable US-ASCII strings, and MUST NOT contain) s
-5 679 M
-( the characters at-sign \('@'\), comma \(','\), or whitespace or control) s
-5 668 M
-( characters \(ASCII codes 32 or less\). Names are case-sensitive, and) s
-5 657 M
-( MUST NOT be longer than 64 characters.) s
-5 635 M
-( Names with the at-sign \('@'\) in them are allocated by the owner of) s
-5 624 M
-( DNS name after the at-sign \(hierarchical allocation in [RFC-2343]\),) s
-5 613 M
-( otherwise the same restrictions as above.) s
-5 591 M
-( Each category of names listed above has a separate namespace.) s
-5 580 M
-( However, using the same name in multiple categories SHOULD be avoided) s
-5 569 M
-( to minimize confusion.) s
-5 547 M
-( Message numbers \(see Section Message Numbers \(Section 7\)\) in the) s
-5 536 M
-( range of 0..191 are allocated via IETF consensus; message numbers in) s
-5 525 M
-( the 192..255 range \(the "Local extensions" set\) are reserved for) s
-5 514 M
-( private use.) s
-5 492 M
-(9. Security Considerations) s
-5 470 M
-( In order to make the entire body of Security Considerations more) s
-5 459 M
-( accessible, Security Considerations for the transport,) s
-5 448 M
-( authentication, and connection documents have been gathered here.) s
-5 426 M
-( The transport protocol [1] provides a confidential channel over an) s
-5 415 M
-( insecure network. It performs server host authentication, key) s
-5 404 M
-( exchange, encryption, and integrity protection. It also derives a) s
-5 393 M
-( unique session id that may be used by higher-level protocols.) s
-5 371 M
-( The authentication protocol [2] provides a suite of mechanisms which) s
-5 360 M
-( can be used to authenticate the client user to the server.) s
-5 349 M
-( Individual mechanisms specified in the in authentication protocol use) s
-5 338 M
-( the session id provided by the transport protocol and/or depend on) s
-5 327 M
-( the security and integrity guarantees of the transport protocol.) s
-5 305 M
-( The connection protocol [3] specifies a mechanism to multiplex) s
-5 294 M
-( multiple streams [channels] of data over the confidential and) s
-5 283 M
-( authenticated transport. It also specifies channels for accessing an) s
-5 272 M
-( interactive shell, for 'proxy-forwarding' various external protocols) s
-5 261 M
-( over the secure transport \(including arbitrary TCP/IP protocols\), and) s
-5 250 M
-( for accessing secure 'subsystems' on the server host.) s
-5 228 M
-(9.1 Pseudo-Random Number Generation) s
-5 206 M
-( This protocol binds each session key to the session by including) s
-5 195 M
-( random, session specific data in the hash used to produce session) s
-5 184 M
-( keys. Special care should be taken to ensure that all of the random) s
-5 173 M
-( numbers are of good quality. If the random data here \(e.g., DH) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( parameters\) are pseudo-random then the pseudo-random number generator) s
-5 679 M
-( should be cryptographically secure \(i.e., its next output not easily) s
-5 668 M
-( guessed even when knowing all previous outputs\) and, furthermore,) s
-5 657 M
-( proper entropy needs to be added to the pseudo-random number) s
-5 646 M
-( generator. RFC 1750 [1750] offers suggestions for sources of random) s
-5 635 M
-( numbers and entropy. Implementors should note the importance of) s
-5 624 M
-( entropy and the well-meant, anecdotal warning about the difficulty in) s
-5 613 M
-( properly implementing pseudo-random number generating functions.) s
-5 591 M
-( The amount of entropy available to a given client or server may) s
-5 580 M
-( sometimes be less than what is required. In this case one must) s
-5 569 M
-( either resort to pseudo-random number generation regardless of) s
-5 558 M
-( insufficient entropy or refuse to run the protocol. The latter is) s
-5 547 M
-( preferable.) s
-5 525 M
-(9.2 Transport) s
-5 503 M
-(9.2.1 Confidentiality) s
-5 481 M
-( It is beyond the scope of this document and the Secure Shell Working) s
-5 470 M
-( Group to analyze or recommend specific ciphers other than the ones) s
-5 459 M
-( which have been established and accepted within the industry. At the) s
-5 448 M
-( time of this writing, ciphers commonly in use include 3DES, ARCFOUR,) s
-5 437 M
-( twofish, serpent and blowfish. AES has been accepted by The) s
-5 426 M
-( published as a US Federal Information Processing Standards [FIPS-197]) s
-5 415 M
-( and the cryptographic community as being acceptable for this purpose) s
-5 404 M
-( as well has accepted AES. As always, implementors and users should) s
-5 393 M
-( check current literature to ensure that no recent vulnerabilities) s
-5 382 M
-( have been found in ciphers used within products. Implementors should) s
-5 371 M
-( also check to see which ciphers are considered to be relatively) s
-5 360 M
-( stronger than others and should recommend their use to users over) s
-5 349 M
-( relatively weaker ciphers. It would be considered good form for an) s
-5 338 M
-( implementation to politely and unobtrusively notify a user that a) s
-5 327 M
-( stronger cipher is available and should be used when a weaker one is) s
-5 316 M
-( actively chosen.) s
-5 294 M
-( The "none" cipher is provided for debugging and SHOULD NOT be used) s
-5 283 M
-( except for that purpose. It's cryptographic properties are) s
-5 272 M
-( sufficiently described in RFC 2410, which will show that its use does) s
-5 261 M
-( not meet the intent of this protocol.) s
-5 239 M
-( The relative merits of these and other ciphers may also be found in) s
-5 228 M
-( current literature. Two references that may provide information on) s
-5 217 M
-( the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of) s
-5 206 M
-( these describe the CBC mode of operation of certain ciphers and the) s
-5 195 M
-( weakness of this scheme. Essentially, this mode is theoretically) s
-5 184 M
-( vulnerable to chosen cipher-text attacks because of the high) s
-5 173 M
-( predictability of the start of packet sequence. However, this attack) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( is still deemed difficult and not considered fully practicable) s
-5 679 M
-( especially if relatively longer block sizes are used.) s
-5 657 M
-( Additionally, another CBC mode attack may be mitigated through the) s
-5 646 M
-( insertion of packets containing SSH_MSG_IGNORE. Without this) s
-5 635 M
-( technique, a specific attack may be successful. For this attack) s
-5 624 M
-( \(commonly known as the Rogaway attack) s
-5 613 M
-( [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]\) to work, the attacker) s
-5 602 M
-( would need to know the IV of the next block that is going to be) s
-5 591 M
-( encrypted. In CBC mode that is the output of the encryption of the) s
-5 580 M
-( previous block. If the attacker does not have any way to see the) s
-5 569 M
-( packet yet \(i.e it is in the internal buffers of the ssh) s
-5 558 M
-( implementation or even in the kernel\) then this attack will not work.) s
-5 547 M
-( If the last packet has been sent out to the network \(i.e the attacker) s
-5 536 M
-( has access to it\) then he can use the attack.) s
-5 514 M
-( In the optimal case an implementor would need to add an extra packet) s
-5 503 M
-( only if the packet has been sent out onto the network and there are) s
-5 492 M
-( no other packets waiting for transmission. Implementors may wish to) s
-5 481 M
-( check to see if there are any unsent packets awaiting transmission,) s
-5 470 M
-( but unfortunately it is not normally easy to obtain this information) s
-5 459 M
-( from the kernel or buffers. If there are not, then a packet) s
-5 448 M
-( containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added) s
-5 437 M
-( to the stream every time the attacker knows the IV that is supposed) s
-5 426 M
-( to be used for the next packet, then the attacker will not be able to) s
-5 415 M
-( guess the correct IV, thus the attack will never be successfull.) s
-5 393 M
-( As an example, consider the following case:) s
-5 360 M
-( Client Server) s
-5 349 M
-( ------ ------) s
-5 338 M
-( TCP\(seq=x, len=500\) ->) s
-5 327 M
-( contains Record 1) s
-5 305 M
-( [500 ms passes, no ACK]) s
-5 283 M
-( TCP\(seq=x, len=1000\) ->) s
-5 272 M
-( contains Records 1,2) s
-5 250 M
-( ACK) s
-5 217 M
-( 1. The Nagle algorithm + TCP retransmits mean that the two records) s
-5 206 M
-( get coalesced into a single TCP segment) s
-5 195 M
-( 2. Record 2 is *not* at the beginning of the TCP segment and never) s
-5 184 M
-( will be, since it gets ACKed.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( 3. Yet, the attack is possible because Record 1 has already been) s
-5 679 M
-( seen.) s
-5 657 M
-( As this example indicates, it's totally unsafe to use the existence) s
-5 646 M
-( of unflushed data in the TCP buffers proper as a guide to whether you) s
-5 635 M
-( need an empty packet, since when you do the second write\(\), the) s
-5 624 M
-( buffers will contain the un-ACKed Record 1.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( On the other hand, it's perfectly safe to have the following) s
-5 679 M
-( situation:) s
-5 646 M
-( Client Server) s
-5 635 M
-( ------ ------) s
-5 624 M
-( TCP\(seq=x, len=500\) ->) s
-5 613 M
-( contains SSH_MSG_IGNORE) s
-5 591 M
-( TCP\(seq=y, len=500\) ->) s
-5 580 M
-( contains Data) s
-5 558 M
-( Provided that the IV for second SSH Record is fixed after the data for) s
-5 547 M
-( the Data packet is determined -i.e. you do:) s
-5 536 M
-( read from user) s
-5 525 M
-( encrypt null packet) s
-5 514 M
-( encrypt data packet) s
-5 481 M
-(9.2.2 Data Integrity) s
-5 459 M
-( This protocol does allow the Data Integrity mechanism to be disabled.) s
-5 448 M
-( Implementors SHOULD be wary of exposing this feature for any purpose) s
-5 437 M
-( other than debugging. Users and administrators SHOULD be explicitly) s
-5 426 M
-( warned anytime the "none" MAC is enabled.) s
-5 404 M
-( So long as the "none" MAC is not used, this protocol provides data) s
-5 393 M
-( integrity.) s
-5 371 M
-( Because MACs use a 32 bit sequence number, they might start to leak) s
-5 360 M
-( information after 2**32 packets have been sent. However, following) s
-5 349 M
-( the rekeying recommendations should prevent this attack. The) s
-5 338 M
-( transport protocol [1] recommends rekeying after one gigabyte of) s
-5 327 M
-( data, and the smallest possible packet is 16 bytes. Therefore,) s
-5 316 M
-( rekeying SHOULD happen after 2**28 packets at the very most.) s
-5 294 M
-(9.2.3 Replay) s
-5 272 M
-( The use of a MAC other than 'none' provides integrity and) s
-5 261 M
-( authentication. In addition, the transport protocol provides a) s
-5 250 M
-( unique session identifier \(bound in part to pseudo-random data that) s
-5 239 M
-( is part of the algorithm and key exchange process\) that can be used) s
-5 228 M
-( by higher level protocols to bind data to a given session and prevent) s
-5 217 M
-( replay of data from prior sessions. For example, the authentication) s
-5 206 M
-( protocol uses this to prevent replay of signatures from previous) s
-5 195 M
-( sessions. Because public key authentication exchanges are) s
-5 184 M
-( cryptographically bound to the session \(i.e., to the initial key) s
-5 173 M
-( exchange\) they cannot be successfully replayed in other sessions.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Note that the session ID can be made public without harming the) s
-5 679 M
-( security of the protocol.) s
-5 657 M
-( If two session happen to have the same session ID [hash of key) s
-5 646 M
-( exchanges] then packets from one can be replayed against the other.) s
-5 635 M
-( It must be stressed that the chances of such an occurrence are,) s
-5 624 M
-( needless to say, minimal when using modern cryptographic methods.) s
-5 613 M
-( This is all the more so true when specifying larger hash function) s
-5 602 M
-( outputs and DH parameters.) s
-5 580 M
-( Replay detection using monotonically increasing sequence numbers as) s
-5 569 M
-( input to the MAC, or HMAC in some cases, is described in [RFC2085] />) s
-5 558 M
-( [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The) s
-5 547 M
-( underlying construct is discussed in [RFC2104]. Essentially a) s
-5 536 M
-( different sequence number in each packet ensures that at least this) s
-5 525 M
-( one input to the MAC function will be unique and will provide a) s
-5 514 M
-( nonrecurring MAC output that is not predictable to an attacker. If) s
-5 503 M
-( the session stays active long enough, however, this sequence number) s
-5 492 M
-( will wrap. This event may provide an attacker an opportunity to) s
-5 481 M
-( replay a previously recorded packet with an identical sequence number) s
-5 470 M
-( but only if the peers have not rekeyed since the transmission of the) s
-5 459 M
-( first packet with that sequence number. If the peers have rekeyed,) s
-5 448 M
-( then the replay will be detected as the MAC check will fail. For) s
-5 437 M
-( this reason, it must be emphasized that peers MUST rekey before a) s
-5 426 M
-( wrap of the sequence numbers. Naturally, if an attacker does attempt) s
-5 415 M
-( to replay a captured packet before the peers have rekeyed, then the) s
-5 404 M
-( receiver of the duplicate packet will not be able to validate the MAC) s
-5 393 M
-( and it will be discarded. The reason that the MAC will fail is) s
-5 382 M
-( because the receiver will formulate a MAC based upon the packet) s
-5 371 M
-( contents, the shared secret, and the expected sequence number. Since) s
-5 360 M
-( the replayed packet will not be using that expected sequence number) s
-5 349 M
-( \(the sequence number of the replayed packet will have already been) s
-5 338 M
-( passed by the receiver\) then the calculated MAC will not match the) s
-5 327 M
-( MAC received with the packet.) s
-5 305 M
-(9.2.4 Man-in-the-middle) s
-5 283 M
-( This protocol makes no assumptions nor provisions for an) s
-5 272 M
-( infrastructure or means for distributing the public keys of hosts. It) s
-5 261 M
-( is expected that this protocol will sometimes be used without first) s
-5 250 M
-( verifying the association between the server host key and the server) s
-5 239 M
-( host name. Such usage is vulnerable to man-in-the-middle attacks.) s
-5 228 M
-( This section describes this and encourages administrators and users) s
-5 217 M
-( to understand the importance of verifying this association before any) s
-5 206 M
-( session is initiated.) s
-5 184 M
-( There are three cases of man-in-the-middle attacks to consider. The) s
-5 173 M
-( first is where an attacker places a device between the client and the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server before the session is initiated. In this case, the attack) s
-5 679 M
-( device is trying to mimic the legitimate server and will offer its) s
-5 668 M
-( public key to the client when the client initiates a session. If it) s
-5 657 M
-( were to offer the public key of the server, then it would not be able) s
-5 646 M
-( to decrypt or sign the transmissions between the legitimate server) s
-5 635 M
-( and the client unless it also had access to the private-key of the) s
-5 624 M
-( host. The attack device will also, simultaneously to this, initiate) s
-5 613 M
-( a session to the legitimate server masquerading itself as the client.) s
-5 602 M
-( If the public key of the server had been securely distributed to the) s
-5 591 M
-( client prior to that session initiation, the key offered to the) s
-5 580 M
-( client by the attack device will not match the key stored on the) s
-5 569 M
-( client. In that case, the user SHOULD be given a warning that the) s
-5 558 M
-( offered host key does not match the host key cached on the client.) s
-5 547 M
-( As described in Section 3.1 of [ARCH], the user may be free to accept) s
-5 536 M
-( the new key and continue the session. It is RECOMMENDED that the) s
-5 525 M
-( warning provide sufficient information to the user of the client) s
-5 514 M
-( device so they may make an informed decision. If the user chooses to) s
-5 503 M
-( continue the session with the stored public-key of the server \(not) s
-5 492 M
-( the public-key offered at the start of the session\), then the session) s
-5 481 M
-( specific data between the attacker and server will be different) s
-5 470 M
-( between the client-to-attacker session and the attacker-to-server) s
-5 459 M
-( sessions due to the randomness discussed above. From this, the) s
-5 448 M
-( attacker will not be able to make this attack work since the attacker) s
-5 437 M
-( will not be able to correctly sign packets containing this session) s
-5 426 M
-( specific data from the server since he does not have the private key) s
-5 415 M
-( of that server.) s
-5 393 M
-( The second case that should be considered is similar to the first) s
-5 382 M
-( case in that it also happens at the time of connection but this case) s
-5 371 M
-( points out the need for the secure distribution of server public) s
-5 360 M
-( keys. If the server public keys are not securely distributed then) s
-5 349 M
-( the client cannot know if it is talking to the intended server. An) s
-5 338 M
-( attacker may use social engineering techniques to pass off server) s
-5 327 M
-( keys to unsuspecting users and may then place a man-in-the-middle) s
-5 316 M
-( attack device between the legitimate server and the clients. If this) s
-5 305 M
-( is allowed to happen then the clients will form client-to-attacker) s
-5 294 M
-( sessions and the attacker will form attacker-to-server sessions and) s
-5 283 M
-( will be able to monitor and manipulate all of the traffic between the) s
-5 272 M
-( clients and the legitimate servers. Server administrators are) s
-5 261 M
-( encouraged to make host key fingerprints available for checking by) s
-5 250 M
-( some means whose security does not rely on the integrity of the) s
-5 239 M
-( actual host keys. Possible mechanisms are discussed in Section 3.1) s
-5 228 M
-( of [SSH-ARCH] and may also include secured Web pages, physical pieces) s
-5 217 M
-( of paper, etc. Implementors SHOULD provide recommendations on how) s
-5 206 M
-( best to do this with their implementation. Because the protocol is) s
-5 195 M
-( extensible, future extensions to the protocol may provide better) s
-5 184 M
-( mechanisms for dealing with the need to know the server's host key) s
-5 173 M
-( before connecting. For example, making the host key fingerprint) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( available through a secure DNS lookup, or using kerberos over gssapi) s
-5 679 M
-( during key exchange to authenticate the server are possibilities.) s
-5 657 M
-( In the third man-in-the-middle case, attackers may attempt to) s
-5 646 M
-( manipulate packets in transit between peers after the session has) s
-5 635 M
-( been established. As described in the Replay part of this section, a) s
-5 624 M
-( successful attack of this nature is very improbable. As in the) s
-5 613 M
-( Replay section, this reasoning does assume that the MAC is secure and) s
-5 602 M
-( that it is infeasible to construct inputs to a MAC algorithm to give) s
-5 591 M
-( a known output. This is discussed in much greater detail in Section) s
-5 580 M
-( 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak) s
-5 569 M
-( enough, then the attacker may be able to specify certain inputs to) s
-5 558 M
-( yield a known MAC. With that they may be able to alter the contents) s
-5 547 M
-( of a packet in transit. Alternatively the attacker may be able to) s
-5 536 M
-( exploit the algorithm vulnerability or weakness to find the shared) s
-5 525 M
-( secret by reviewing the MACs from captured packets. In either of) s
-5 514 M
-( those cases, an attacker could construct a packet or packets that) s
-5 503 M
-( could be inserted into an SSH stream. To prevent that, implementors) s
-5 492 M
-( are encouraged to utilize commonly accepted MAC algorithms and) s
-5 481 M
-( administrators are encouraged to watch current literature and) s
-5 470 M
-( discussions of cryptography to ensure that they are not using a MAC) s
-5 459 M
-( algorithm that has a recently found vulnerability or weakness.) s
-5 437 M
-( In summary, the use of this protocol without a reliable association) s
-5 426 M
-( of the binding between a host and its host keys is inherently) s
-5 415 M
-( insecure and is NOT RECOMMENDED. It may however be necessary in) s
-5 404 M
-( non-security critical environments, and will still provide protection) s
-5 393 M
-( against passive attacks. Implementors of protocols and applications) s
-5 382 M
-( running on top of this protocol should keep this possibility in mind.) s
-5 360 M
-(9.2.5 Denial-of-service) s
-5 338 M
-( This protocol is designed to be used over a reliable transport. If) s
-5 327 M
-( transmission errors or message manipulation occur, the connection is) s
-5 316 M
-( closed. The connection SHOULD be re-established if this occurs.) s
-5 305 M
-( Denial of service attacks of this type \("wire cutter"\) are almost) s
-5 294 M
-( impossible to avoid.) s
-5 272 M
-( In addition, this protocol is vulnerable to Denial of Service attacks) s
-5 261 M
-( because an attacker can force the server to go through the CPU and) s
-5 250 M
-( memory intensive tasks of connection setup and key exchange without) s
-5 239 M
-( authenticating. Implementors SHOULD provide features that make this) s
-5 228 M
-( more difficult. For example, only allowing connections from a subset) s
-5 217 M
-( of IPs known to have valid users.) s
-5 195 M
-(9.2.6 Covert Channels) s
-5 173 M
-( The protocol was not designed to eliminate covert channels. For) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( example, the padding, SSH_MSG_IGNORE messages, and several other) s
-5 679 M
-( places in the protocol can be used to pass covert information, and) s
-5 668 M
-( the recipient has no reliable way to verify whether such information) s
-5 657 M
-( is being sent.) s
-5 635 M
-(9.2.7 Forward Secrecy) s
-5 613 M
-( It should be noted that the Diffie-Hellman key exchanges may provide) s
-5 602 M
-( perfect forward secrecy \(PFS\). PFS is essentially defined as the) s
-5 591 M
-( cryptographic property of a key-establishment protocol in which the) s
-5 580 M
-( compromise of a session key or long-term private key after a given) s
-5 569 M
-( session does not cause the compromise of any earlier session. [ANSI) s
-5 558 M
-( T1.523-2001] SSHv2 sessions resulting from a key exchange using) s
-5 547 M
-( diffie-hellman-group1-sha1 are secure even if private keying/) s
-5 536 M
-( authentication material is later revealed, but not if the session) s
-5 525 M
-( keys are revealed. So, given this definition of PFS, SSHv2 does have) s
-5 514 M
-( PFS. It is hoped that all other key exchange mechanisms proposed and) s
-5 503 M
-( used in the future will also provide PFS. This property is not) s
-5 492 M
-( commuted to any of the applications or protocols using SSH as a) s
-5 481 M
-( transport however. The transport layer of SSH provides) s
-5 470 M
-( confidentiality for password authentication and other methods that) s
-5 459 M
-( rely on secret data.) s
-5 437 M
-( Of course, if the DH private parameters for the client and server are) s
-5 426 M
-( revealed then the session key is revealed, but these items can be) s
-5 415 M
-( thrown away after the key exchange completes. It's worth pointing) s
-5 404 M
-( out that these items should not be allowed to end up on swap space) s
-5 393 M
-( and that they should be erased from memory as soon as the key) s
-5 382 M
-( exchange completes.) s
-5 360 M
-(9.3 Authentication Protocol) s
-5 338 M
-( The purpose of this protocol is to perform client user) s
-5 327 M
-( authentication. It assumes that this run over a secure transport) s
-5 316 M
-( layer protocol, which has already authenticated the server machine,) s
-5 305 M
-( established an encrypted communications channel, and computed a) s
-5 294 M
-( unique session identifier for this session.) s
-5 272 M
-( Several authentication methods with different security) s
-5 261 M
-( characteristics are allowed. It is up to the server's local policy) s
-5 250 M
-( to decide which methods \(or combinations of methods\) it is willing to) s
-5 239 M
-( accept for each user. Authentication is no stronger than the weakest) s
-5 228 M
-( combination allowed.) s
-5 206 M
-( The server may go into a "sleep" period after repeated unsuccessful) s
-5 195 M
-( authentication attempts to make key search more difficult for) s
-5 184 M
-( attackers. Care should be taken so that this doesn't become a) s
-5 173 M
-( self-denial of service vector.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(9.3.1 Weak Transport) s
-5 668 M
-( If the transport layer does not provide confidentiality,) s
-5 657 M
-( authentication methods that rely on secret data SHOULD be disabled.) s
-5 646 M
-( If it does not provide strong integrity protection, requests to) s
-5 635 M
-( change authentication data \(e.g. a password change\) SHOULD be) s
-5 624 M
-( disabled to prevent an attacker from modifying the ciphertext) s
-5 613 M
-( without being noticed, or rendering the new authentication data) s
-5 602 M
-( unusable \(denial of service\).) s
-5 580 M
-( The assumption as stated above that the Authentication Protocol only) s
-5 569 M
-( run over a secure transport that has previously authenticated the) s
-5 558 M
-( server is very important to note. People deploying SSH are reminded) s
-5 547 M
-( of the consequences of man-in-the-middle attacks if the client does) s
-5 536 M
-( not have a very strong a priori association of the server with the) s
-5 525 M
-( host key of that server. Specifically for the case of the) s
-5 514 M
-( Authentication Protocol the client may form a session to a) s
-5 503 M
-( man-in-the-middle attack device and divulge user credentials such as) s
-5 492 M
-( their username and password. Even in the cases of authentication) s
-5 481 M
-( where no user credentials are divulged, an attacker may still gain) s
-5 470 M
-( information they shouldn't have by capturing key-strokes in much the) s
-5 459 M
-( same way that a honeypot works.) s
-5 437 M
-(9.3.2 Debug messages) s
-5 415 M
-( Special care should be taken when designing debug messages. These) s
-5 404 M
-( messages may reveal surprising amounts of information about the host) s
-5 393 M
-( if not properly designed. Debug messages can be disabled \(during) s
-5 382 M
-( user authentication phase\) if high security is required.) s
-5 371 M
-( Administrators of host machines should make all attempts to) s
-5 360 M
-( compartmentalize all event notification messages and protect them) s
-5 349 M
-( from unwarranted observation. Developers should be aware of the) s
-5 338 M
-( sensitive nature of some of the normal event messages and debug) s
-5 327 M
-( messages and may want to provide guidance to administrators on ways) s
-5 316 M
-( to keep this information away from unauthorized people. Developers) s
-5 305 M
-( should consider minimizing the amount of sensitive information) s
-5 294 M
-( obtainable by users during the authentication phase in accordance) s
-5 283 M
-( with the local policies. For this reason, it is RECOMMENDED that) s
-5 272 M
-( debug messages be initially disabled at the time of deployment and) s
-5 261 M
-( require an active decision by an administrator to allow them to be) s
-5 250 M
-( enabled. It is also RECOMMENDED that a message expressing this) s
-5 239 M
-( concern be presented to the administrator of a system when the action) s
-5 228 M
-( is taken to enable debugging messages.) s
-5 206 M
-(9.3.3 Local security policy) s
-5 184 M
-( Implementer MUST ensure that the credentials provided validate the) s
-5 173 M
-( professed user and also MUST ensure that the local policy of the) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( server permits the user the access requested. In particular, because) s
-5 679 M
-( of the flexible nature of the SSH connection protocol, it may not be) s
-5 668 M
-( possible to determine the local security policy, if any, that should) s
-5 657 M
-( apply at the time of authentication because the kind of service being) s
-5 646 M
-( requested is not clear at that instant. For example, local policy) s
-5 635 M
-( might allow a user to access files on the server, but not start an) s
-5 624 M
-( interactive shell. However, during the authentication protocol, it is) s
-5 613 M
-( not known whether the user will be accessing files or attempting to) s
-5 602 M
-( use an interactive shell, or even both. In any event, where local) s
-5 591 M
-( security policy for the server host exists, it MUST be applied and) s
-5 580 M
-( enforced correctly.) s
-5 558 M
-( Implementors are encouraged to provide a default local policy and) s
-5 547 M
-( make its parameters known to administrators and users. At the) s
-5 536 M
-( discretion of the implementors, this default policy may be along the) s
-5 525 M
-( lines of 'anything goes' where there are no restrictions placed upon) s
-5 514 M
-( users, or it may be along the lines of 'excessively restrictive' in) s
-5 503 M
-( which case the administrators will have to actively make changes to) s
-5 492 M
-( this policy to meet their needs. Alternatively, it may be some) s
-5 481 M
-( attempt at providing something practical and immediately useful to) s
-5 470 M
-( the administrators of the system so they don't have to put in much) s
-5 459 M
-( effort to get SSH working. Whatever choice is made MUST be applied) s
-5 448 M
-( and enforced as required above.) s
-5 426 M
-(9.3.4 Public key authentication) s
-5 404 M
-( The use of public-key authentication assumes that the client host has) s
-5 393 M
-( not been compromised. It also assumes that the private-key of the) s
-5 382 M
-( server host has not been compromised.) s
-5 360 M
-( This risk can be mitigated by the use of passphrases on private keys;) s
-5 349 M
-( however, this is not an enforceable policy. The use of smartcards,) s
-5 338 M
-( or other technology to make passphrases an enforceable policy is) s
-5 327 M
-( suggested.) s
-5 305 M
-( The server could require both password and public-key authentication,) s
-5 294 M
-( however, this requires the client to expose its password to the) s
-5 283 M
-( server \(see section on password authentication below.\)) s
-5 261 M
-(9.3.5 Password authentication) s
-5 239 M
-( The password mechanism as specified in the authentication protocol) s
-5 228 M
-( assumes that the server has not been compromised. If the server has) s
-5 217 M
-( been compromised, using password authentication will reveal a valid) s
-5 206 M
-( username / password combination to the attacker, which may lead to) s
-5 195 M
-( further compromises.) s
-5 173 M
-( This vulnerability can be mitigated by using an alternative form of) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( authentication. For example, public-key authentication makes no) s
-5 679 M
-( assumptions about security on the server.) s
-5 657 M
-(9.3.6 Host based authentication) s
-5 635 M
-( Host based authentication assumes that the client has not been) s
-5 624 M
-( compromised. There are no mitigating strategies, other than to use) s
-5 613 M
-( host based authentication in combination with another authentication) s
-5 602 M
-( method.) s
-5 580 M
-(9.4 Connection protocol) s
-5 558 M
-(9.4.1 End point security) s
-5 536 M
-( End point security is assumed by the connection protocol. If the) s
-5 525 M
-( server has been compromised, any terminal sessions, port forwarding,) s
-5 514 M
-( or systems accessed on the host are compromised. There are no) s
-5 503 M
-( mitigating factors for this.) s
-5 481 M
-( If the client end point has been compromised, and the server fails to) s
-5 470 M
-( stop the attacker at the authentication protocol, all services) s
-5 459 M
-( exposed \(either as subsystems or through forwarding\) will be) s
-5 448 M
-( vulnerable to attack. Implementors SHOULD provide mechanisms for) s
-5 437 M
-( administrators to control which services are exposed to limit the) s
-5 426 M
-( vulnerability of other services.) s
-5 404 M
-( These controls might include controlling which machines and ports can) s
-5 393 M
-( be target in 'port-forwarding' operations, which users are allowed to) s
-5 382 M
-( use interactive shell facilities, or which users are allowed to use) s
-5 371 M
-( exposed subsystems.) s
-5 349 M
-(9.4.2 Proxy forwarding) s
-5 327 M
-( The SSH connection protocol allows for proxy forwarding of other) s
-5 316 M
-( protocols such as SNMP, POP3, and HTTP. This may be a concern for) s
-5 305 M
-( network administrators who wish to control the access of certain) s
-5 294 M
-( applications by users located outside of their physical location.) s
-5 283 M
-( Essentially, the forwarding of these protocols may violate site) s
-5 272 M
-( specific security policies as they may be undetectably tunneled) s
-5 261 M
-( through a firewall. Implementors SHOULD provide an administrative) s
-5 250 M
-( mechanism to control the proxy forwarding functionality so that site) s
-5 239 M
-( specific security policies may be upheld.) s
-5 217 M
-( In addition, a reverse proxy forwarding functionality is available,) s
-5 206 M
-( which again can be used to bypass firewall controls.) s
-5 184 M
-( As indicated above, end-point security is assumed during proxy) s
-5 173 M
-( forwarding operations. Failure of end-point security will compromise) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( all data passed over proxy forwarding.) s
-5 668 M
-(9.4.3 X11 forwarding) s
-5 646 M
-( Another form of proxy forwarding provided by the ssh connection) s
-5 635 M
-( protocol is the forwarding of the X11 protocol. If end-point) s
-5 624 M
-( security has been compromised, X11 forwarding may allow attacks) s
-5 613 M
-( against the X11 server. Users and administrators should, as a matter) s
-5 602 M
-( of course, use appropriate X11 security mechanisms to prevent) s
-5 591 M
-( unauthorized use of the X11 server. Implementors, administrators and) s
-5 580 M
-( users who wish to further explore the security mechanisms of X11 are) s
-5 569 M
-( invited to read [SCHEIFLER] and analyze previously reported problems) s
-5 558 M
-( with the interactions between SSH forwarding and X11 in CERT) s
-5 547 M
-( vulnerabilities VU#363181 and VU#118892 [CERT].) s
-5 525 M
-( X11 display forwarding with SSH, by itself, is not sufficient to) s
-5 514 M
-( correct well known problems with X11 security [VENEMA]. However, X11) s
-5 503 M
-( display forwarding in SSHv2 \(or other, secure protocols\), combined) s
-5 492 M
-( with actual and pseudo-displays which accept connections only over) s
-5 481 M
-( local IPC mechanisms authorized by permissions or ACLs, does correct) s
-5 470 M
-( many X11 security problems as long as the "none" MAC is not used. It) s
-5 459 M
-( is RECOMMENDED that X11 display implementations default to allowing) s
-5 448 M
-( display opens only over local IPC. It is RECOMMENDED that SSHv2) s
-5 437 M
-( server implementations that support X11 forwarding default to) s
-5 426 M
-( allowing display opens only over local IPC. On single-user systems) s
-5 415 M
-( it might be reasonable to default to allowing local display opens) s
-5 404 M
-( over TCP/IP.) s
-5 382 M
-( Implementors of the X11 forwarding protocol SHOULD implement the) s
-5 371 M
-( magic cookie access checking spoofing mechanism as described in) s
-5 360 M
-( [ssh-connect] as an additional mechanism to prevent unauthorized use) s
-5 349 M
-( of the proxy.) s
-5 327 M
-(Normative References) s
-5 305 M
-( [SSH-ARCH]) s
-5 294 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 283 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 261 M
-( [SSH-TRANS]) s
-5 250 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 239 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 217 M
-( [SSH-USERAUTH]) s
-5 206 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 195 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 173 M
-( [SSH-CONNECT]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 679 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 657 M
-( [SSH-NUMBERS]) s
-5 646 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 635 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 624 M
-( 2003.) s
-5 602 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 591 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 569 M
-(Informative References) s
-5 547 M
-( [FIPS-186]) s
-5 536 M
-( Federal Information Processing Standards Publication,) s
-5 525 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 503 M
-( [FIPS-197]) s
-5 492 M
-( National Institue of Standards and Technology, "FIPS 197,) s
-5 481 M
-( Specification for the Advanced Encryption Standard",) s
-5 470 M
-( November 2001.) s
-5 448 M
-( [ANSI T1.523-2001]) s
-5 437 M
-( American National Standards Insitute, Inc., "Telecom) s
-5 426 M
-( Glossary 2000", February 2001.) s
-5 404 M
-( [SCHEIFLER]) s
-5 393 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 382 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 371 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 349 M
-( [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol) s
-5 338 M
-( Specification", STD 8, RFC 854, May 1983.) s
-5 316 M
-( [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams) s
-5 305 M
-( over Ethernet networks", STD 41, RFC 894, April 1984.) s
-5 283 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 272 M
-( STD 13, RFC 1034, November 1987.) s
-5 250 M
-( [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for) s
-5 239 M
-( multi-protocol transmission of datagrams over) s
-5 228 M
-( Point-to-Point links", RFC 1134, November 1989.) s
-5 206 M
-( [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.) s
-5 184 M
-( [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network) s
-5 173 M
-( Authentication Service \(V5\)", RFC 1510, September 1993.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,) s
-5 679 M
-( October 1994.) s
-5 657 M
-( [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness) s
-5 646 M
-( Recommendations for Security", RFC 1750, December 1994.) s
-5 624 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 613 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 591 M
-( [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC) s
-5 580 M
-( 1964, June 1996.) s
-5 558 M
-( [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism) s
-5 547 M
-( \(SPKM\)", RFC 2025, October 1996.) s
-5 525 M
-( [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with) s
-5 514 M
-( Replay Prevention", RFC 2085, February 1997.) s
-5 492 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 481 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 470 M
-( February 1997.) s
-5 448 M
-( [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.) s
-5 437 M
-( and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,) s
-5 426 M
-( January 1999.) s
-5 404 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 393 M
-( 10646", RFC 2279, January 1998.) s
-5 371 M
-( [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and) s
-5 360 M
-( Its Use With IPsec", RFC 2410, November 1998.) s
-5 338 M
-( [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an) s
-5 327 M
-( IANA Considerations Section in RFCs", BCP 26, RFC 2434,) s
-5 316 M
-( October 1998.) s
-5 294 M
-( [RFC2743] Linn, J., "Generic Security Service Application Program) s
-5 283 M
-( Interface Version 2, Update 1", RFC 2743, January 2000.) s
-5 261 M
-( [SCHNEIER]) s
-5 250 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 239 M
-( protocols algorithms and source in code in C", 1996.) s
-5 217 M
-( [KAUFMAN,PERLMAN,SPECINER]) s
-5 206 M
-( Kaufman, C., Perlman, R. and M. Speciner, "Network) s
-5 195 M
-( Security: PRIVATE Communication in a PUBLIC World", 1995.) s
-5 173 M
-( [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( index_red.html".) s
-5 668 M
-( [VENEMA] Venema, W., "Murphy's Law and Computer Security",) s
-5 657 M
-( Proceedings of 6th USENIX Security Symposium, San Jose CA) s
-5 646 M
-( http://www.usenix.org/publications/library/proceedings/) s
-5 635 M
-( sec96/venema.html, July 1996.) s
-5 613 M
-( [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",) s
-5 602 M
-( Unpublished paper http://www.cs.ucdavis.edu/~rogaway/) s
-5 591 M
-( papers/draft-rogaway-ipsec-comments-00.txt, 1996.) s
-5 569 M
-( [DAI] Dai, W., "An attack against SSH2 protocol", Email to the) s
-5 558 M
-( SECSH Working Group [email protected] ftp://) s
-5 547 M
-( ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb) s
-5 536 M
-( 2002.) s
-5 514 M
-( [BELLARE,KOHNO,NAMPREMPRE]) s
-5 503 M
-( Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated) s
-5 492 M
-( Encryption in SSH: Fixing the SSH Binary Packet Protocol",) s
-5 481 M
-( , Sept 2002.) s
-5 448 M
-(Authors' Addresses) s
-5 426 M
-( Tatu Ylonen) s
-5 415 M
-( SSH Communications Security Corp) s
-5 404 M
-( Fredrikinkatu 42) s
-5 393 M
-( HELSINKI FIN-00100) s
-5 382 M
-( Finland) s
-5 360 M
-( EMail: [email protected]) s
-5 327 M
-( Darren J. Moffat \(editor\)) s
-5 316 M
-( Sun Microsystems, Inc) s
-5 305 M
-( 17 Network Circle) s
-5 294 M
-( Menlo Park CA 94025) s
-5 283 M
-( USA) s
-5 261 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Protocol Architecture Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt b/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
deleted file mode 100644
index 18070e8485..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-architecture-15.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Protocol Architecture
- draft-ietf-secsh-architecture-15.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the
- architecture of the SSH protocol, as well as the notation and
- terminology used in SSH protocol documents. It also discusses the SSH
- algorithm naming system that allows local extensions. The SSH
- protocol consists of three major components: The Transport Layer
- Protocol provides server authentication, confidentiality, and
- integrity with perfect forward secrecy. The User Authentication
- Protocol authenticates the client to the server. The Connection
- Protocol multiplexes the encrypted tunnel into several logical
- channels. Details of these protocols are described in separate
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- documents.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Specification of Requirements . . . . . . . . . . . . . . . 3
- 4. Architecture . . . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Host Keys . . . . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.3 Policy Issues . . . . . . . . . . . . . . . . . . . . . . . 5
- 4.4 Security Properties . . . . . . . . . . . . . . . . . . . . 6
- 4.5 Packet Size and Overhead . . . . . . . . . . . . . . . . . . 6
- 4.6 Localization and Character Set Support . . . . . . . . . . . 7
- 5. Data Type Representations Used in the SSH Protocols . . . . 8
- 6. Algorithm Naming . . . . . . . . . . . . . . . . . . . . . . 10
- 7. Message Numbers . . . . . . . . . . . . . . . . . . . . . . 11
- 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . 11
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 12
- 9.1 Pseudo-Random Number Generation . . . . . . . . . . . . . . 12
- 9.2 Transport . . . . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.1 Confidentiality . . . . . . . . . . . . . . . . . . . . . . 13
- 9.2.2 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.3 Replay . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
- 9.2.4 Man-in-the-middle . . . . . . . . . . . . . . . . . . . . . 17
- 9.2.5 Denial-of-service . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.6 Covert Channels . . . . . . . . . . . . . . . . . . . . . . 19
- 9.2.7 Forward Secrecy . . . . . . . . . . . . . . . . . . . . . . 20
- 9.3 Authentication Protocol . . . . . . . . . . . . . . . . . . 20
- 9.3.1 Weak Transport . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.2 Debug messages . . . . . . . . . . . . . . . . . . . . . . . 21
- 9.3.3 Local security policy . . . . . . . . . . . . . . . . . . . 21
- 9.3.4 Public key authentication . . . . . . . . . . . . . . . . . 22
- 9.3.5 Password authentication . . . . . . . . . . . . . . . . . . 22
- 9.3.6 Host based authentication . . . . . . . . . . . . . . . . . 23
- 9.4 Connection protocol . . . . . . . . . . . . . . . . . . . . 23
- 9.4.1 End point security . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.2 Proxy forwarding . . . . . . . . . . . . . . . . . . . . . . 23
- 9.4.3 X11 forwarding . . . . . . . . . . . . . . . . . . . . . . . 24
- Normative References . . . . . . . . . . . . . . . . . . . . 24
- Informative References . . . . . . . . . . . . . . . . . . . 25
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. It consists of three major
- components:
- o The Transport Layer Protocol [SSH-TRANS] provides server
- authentication, confidentiality, and integrity. It may optionally
- also provide compression. The transport layer will typically be
- run over a TCP/IP connection, but might also be used on top of any
- other reliable data stream.
- o The User Authentication Protocol [SSH-USERAUTH] authenticates the
- client-side user to the server. It runs over the transport layer
- protocol.
- o The Connection Protocol [SSH-CONNECT] multiplexes the encrypted
- tunnel into several logical channels. It runs over the user
- authentication protocol.
-
- The client sends a service request once a secure transport layer
- connection has been established. A second service request is sent
- after user authentication is complete. This allows new protocols to
- be defined and coexist with the protocols listed above.
-
- The connection protocol provides channels that can be used for a wide
- range of purposes. Standard methods are provided for setting up
- secure interactive shell sessions and for forwarding ("tunneling")
- arbitrary TCP/IP ports and X11 connections.
-
-3. Specification of Requirements
-
- All documents related to the SSH protocols shall use the keywords
- "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
- "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" to describe
- requirements. They are to be interpreted as described in [RFC2119].
-
-4. Architecture
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-4.1 Host Keys
-
- Each server host SHOULD have a host key. Hosts MAY have multiple
- host keys using multiple different algorithms. Multiple hosts MAY
- share the same host key. If a host has keys at all, it MUST have at
- least one key using each REQUIRED public key algorithm (DSS
- [FIPS-186]).
-
- The server host key is used during key exchange to verify that the
- client is really talking to the correct server. For this to be
- possible, the client must have a priori knowledge of the server's
- public host key.
-
- Two different trust models can be used:
- o The client has a local database that associates each host name (as
- typed by the user) with the corresponding public host key. This
- method requires no centrally administered infrastructure, and no
- third-party coordination. The downside is that the database of
- name-to-key associations may become burdensome to maintain.
- o The host name-to-key association is certified by some trusted
- certification authority. The client only knows the CA root key,
- and can verify the validity of all host keys certified by accepted
- CAs.
-
- The second alternative eases the maintenance problem, since
- ideally only a single CA key needs to be securely stored on the
- client. On the other hand, each host key must be appropriately
- certified by a central authority before authorization is possible.
- Also, a lot of trust is placed on the central infrastructure.
-
- The protocol provides the option that the server name - host key
- association is not checked when connecting to the host for the first
- time. This allows communication without prior communication of host
- keys or certification. The connection still provides protection
- against passive listening; however, it becomes vulnerable to active
- man-in-the-middle attacks. Implementations SHOULD NOT normally allow
- such connections by default, as they pose a potential security
- problem. However, as there is no widely deployed key infrastructure
- available on the Internet yet, this option makes the protocol much
- more usable during the transition time until such an infrastructure
- emerges, while still providing a much higher level of security than
- that offered by older solutions (e.g. telnet [RFC-854] and rlogin
- [RFC-1282]).
-
- Implementations SHOULD try to make the best effort to check host
- keys. An example of a possible strategy is to only accept a host key
- without checking the first time a host is connected, save the key in
- a local database, and compare against that key on all future
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- connections to that host.
-
- Implementations MAY provide additional methods for verifying the
- correctness of host keys, e.g. a hexadecimal fingerprint derived from
- the SHA-1 hash of the public key. Such fingerprints can easily be
- verified by using telephone or other external communication channels.
-
- All implementations SHOULD provide an option to not accept host keys
- that cannot be verified.
-
- We believe that ease of use is critical to end-user acceptance of
- security solutions, and no improvement in security is gained if the
- new solutions are not used. Thus, providing the option not to check
- the server host key is believed to improve the overall security of
- the Internet, even though it reduces the security of the protocol in
- configurations where it is allowed.
-
-4.2 Extensibility
-
- We believe that the protocol will evolve over time, and some
- organizations will want to use their own encryption, authentication
- and/or key exchange methods. Central registration of all extensions
- is cumbersome, especially for experimental or classified features.
- On the other hand, having no central registration leads to conflicts
- in method identifiers, making interoperability difficult.
-
- We have chosen to identify algorithms, methods, formats, and
- extension protocols with textual names that are of a specific format.
- DNS names are used to create local namespaces where experimental or
- classified extensions can be defined without fear of conflicts with
- other implementations.
-
- One design goal has been to keep the base protocol as simple as
- possible, and to require as few algorithms as possible. However, all
- implementations MUST support a minimal set of algorithms to ensure
- interoperability (this does not imply that the local policy on all
- hosts would necessary allow these algorithms). The mandatory
- algorithms are specified in the relevant protocol documents.
-
- Additional algorithms, methods, formats, and extension protocols can
- be defined in separate drafts. See Section Algorithm Naming (Section
- 6) for more information.
-
-4.3 Policy Issues
-
- The protocol allows full negotiation of encryption, integrity, key
- exchange, compression, and public key algorithms and formats.
- Encryption, integrity, public key, and compression algorithms can be
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- different for each direction.
-
- The following policy issues SHOULD be addressed in the configuration
- mechanisms of each implementation:
- o Encryption, integrity, and compression algorithms, separately for
- each direction. The policy MUST specify which is the preferred
- algorithm (e.g. the first algorithm listed in each category).
- o Public key algorithms and key exchange method to be used for host
- authentication. The existence of trusted host keys for different
- public key algorithms also affects this choice.
- o The authentication methods that are to be required by the server
- for each user. The server's policy MAY require multiple
- authentication for some or all users. The required algorithms MAY
- depend on the location where the user is trying to log in from.
- o The operations that the user is allowed to perform using the
- connection protocol. Some issues are related to security; for
- example, the policy SHOULD NOT allow the server to start sessions
- or run commands on the client machine, and MUST NOT allow
- connections to the authentication agent unless forwarding such
- connections has been requested. Other issues, such as which TCP/
- IP ports can be forwarded and by whom, are clearly issues of local
- policy. Many of these issues may involve traversing or bypassing
- firewalls, and are interrelated with the local security policy.
-
-4.4 Security Properties
-
- The primary goal of the SSH protocol is improved security on the
- Internet. It attempts to do this in a way that is easy to deploy,
- even at the cost of absolute security.
- o All encryption, integrity, and public key algorithms used are
- well-known, well-established algorithms.
- o All algorithms are used with cryptographically sound key sizes
- that are believed to provide protection against even the strongest
- cryptanalytic attacks for decades.
- o All algorithms are negotiated, and in case some algorithm is
- broken, it is easy to switch to some other algorithm without
- modifying the base protocol.
-
- Specific concessions were made to make wide-spread fast deployment
- easier. The particular case where this comes up is verifying that
- the server host key really belongs to the desired host; the protocol
- allows the verification to be left out (but this is NOT RECOMMENDED).
- This is believed to significantly improve usability in the short
- term, until widespread Internet public key infrastructures emerge.
-
-4.5 Packet Size and Overhead
-
- Some readers will worry about the increase in packet size due to new
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- headers, padding, and MAC. The minimum packet size is in the order
- of 28 bytes (depending on negotiated algorithms). The increase is
- negligible for large packets, but very significant for one-byte
- packets (telnet-type sessions). There are, however, several factors
- that make this a non-issue in almost all cases:
- o The minimum size of a TCP/IP header is 32 bytes. Thus, the
- increase is actually from 33 to 51 bytes (roughly).
- o The minimum size of the data field of an Ethernet packet is 46
- bytes [RFC-894]. Thus, the increase is no more than 5 bytes. When
- Ethernet headers are considered, the increase is less than 10
- percent.
- o The total fraction of telnet-type data in the Internet is
- negligible, even with increased packet sizes.
-
- The only environment where the packet size increase is likely to have
- a significant effect is PPP [RFC-1134] over slow modem lines (PPP
- compresses the TCP/IP headers, emphasizing the increase in packet
- size). However, with modern modems, the time needed to transfer is in
- the order of 2 milliseconds, which is a lot faster than people can
- type.
-
- There are also issues related to the maximum packet size. To
- minimize delays in screen updates, one does not want excessively
- large packets for interactive sessions. The maximum packet size is
- negotiated separately for each channel.
-
-4.6 Localization and Character Set Support
-
- For the most part, the SSH protocols do not directly pass text that
- would be displayed to the user. However, there are some places where
- such data might be passed. When applicable, the character set for the
- data MUST be explicitly specified. In most places, ISO 10646 with
- UTF-8 encoding is used [RFC-2279]. When applicable, a field is also
- provided for a language tag [RFC-3066].
-
- One big issue is the character set of the interactive session. There
- is no clear solution, as different applications may display data in
- different formats. Different types of terminal emulation may also be
- employed in the client, and the character set to be used is
- effectively determined by the terminal emulation. Thus, no place is
- provided for directly specifying the character set or encoding for
- terminal session data. However, the terminal emulation type (e.g.
- "vt100") is transmitted to the remote site, and it implicitly
- specifies the character set and encoding. Applications typically use
- the terminal type to determine what character set they use, or the
- character set is determined using some external means. The terminal
- emulation may also allow configuring the default character set. In
- any case, the character set for the terminal session is considered
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- primarily a client local issue.
-
- Internal names used to identify algorithms or protocols are normally
- never displayed to users, and must be in US-ASCII.
-
- The client and server user names are inherently constrained by what
- the server is prepared to accept. They might, however, occasionally
- be displayed in logs, reports, etc. They MUST be encoded using ISO
- 10646 UTF-8, but other encodings may be required in some cases. It
- is up to the server to decide how to map user names to accepted user
- names. Straight bit-wise binary comparison is RECOMMENDED.
-
- For localization purposes, the protocol attempts to minimize the
- number of textual messages transmitted. When present, such messages
- typically relate to errors, debugging information, or some externally
- configured data. For data that is normally displayed, it SHOULD be
- possible to fetch a localized message instead of the transmitted
- message by using a numerical code. The remaining messages SHOULD be
- configurable.
-
-5. Data Type Representations Used in the SSH Protocols
- byte
-
- A byte represents an arbitrary 8-bit value (octet) [RFC-1700].
- Fixed length data is sometimes represented as an array of bytes,
- written byte[n], where n is the number of bytes in the array.
-
- boolean
-
- A boolean value is stored as a single byte. The value 0
- represents FALSE, and the value 1 represents TRUE. All non-zero
- values MUST be interpreted as TRUE; however, applications MUST NOT
- store values other than 0 and 1.
-
- uint32
-
- Represents a 32-bit unsigned integer. Stored as four bytes in the
- order of decreasing significance (network byte order). For
- example, the value 699921578 (0x29b7f4aa) is stored as 29 b7 f4
- aa.
-
- uint64
-
- Represents a 64-bit unsigned integer. Stored as eight bytes in
- the order of decreasing significance (network byte order).
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- string
-
- Arbitrary length binary string. Strings are allowed to contain
- arbitrary binary data, including null characters and 8-bit
- characters. They are stored as a uint32 containing its length
- (number of bytes that follow) and zero (= empty string) or more
- bytes that are the value of the string. Terminating null
- characters are not used.
-
- Strings are also used to store text. In that case, US-ASCII is
- used for internal names, and ISO-10646 UTF-8 for text that might
- be displayed to the user. The terminating null character SHOULD
- NOT normally be stored in the string.
-
- For example, the US-ASCII string "testing" is represented as 00 00
- 00 07 t e s t i n g. The UTF8 mapping does not alter the encoding
- of US-ASCII characters.
-
- mpint
-
- Represents multiple precision integers in two's complement format,
- stored as a string, 8 bits per byte, MSB first. Negative numbers
- have the value 1 as the most significant bit of the first byte of
- the data partition. If the most significant bit would be set for a
- positive number, the number MUST be preceded by a zero byte.
- Unnecessary leading bytes with the value 0 or 255 MUST NOT be
- included. The value zero MUST be stored as a string with zero
- bytes of data.
-
- By convention, a number that is used in modular computations in
- Z_n SHOULD be represented in the range 0 <= x < n.
-
- Examples:
- value (hex) representation (hex)
- ---------------------------------------------------------------
- 0 00 00 00 00
- 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7
- 80 00 00 00 02 00 80
- -1234 00 00 00 02 ed cc
- -deadbeef 00 00 00 05 ff 21 52 41 11
-
-
-
- name-list
-
- A string containing a comma separated list of names. A name list
- is represented as a uint32 containing its length (number of bytes
- that follow) followed by a comma-separated list of zero or more
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- names. A name MUST be non-zero length, and it MUST NOT contain a
- comma (','). Context may impose additional restrictions on the
- names; for example, the names in a list may have to be valid
- algorithm identifier (see Algorithm Naming below), or [RFC-3066]
- language tags. The order of the names in a list may or may not be
- significant, also depending on the context where the list is is
- used. Terminating NUL characters are not used, neither for the
- individual names, nor for the list as a whole.
-
- Examples:
- value representation (hex)
- ---------------------------------------
- (), the empty list 00 00 00 00
- ("zlib") 00 00 00 04 7a 6c 69 62
- ("zlib", "none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65
-
-
-
-
-6. Algorithm Naming
-
- The SSH protocols refer to particular hash, encryption, integrity,
- compression, and key exchange algorithms or protocols by names.
- There are some standard algorithms that all implementations MUST
- support. There are also algorithms that are defined in the protocol
- specification but are OPTIONAL. Furthermore, it is expected that
- some organizations will want to use their own algorithms.
-
- In this protocol, all algorithm identifiers MUST be printable
- US-ASCII non-empty strings no longer than 64 characters. Names MUST
- be case-sensitive.
-
- There are two formats for algorithm names:
- o Names that do not contain an at-sign (@) are reserved to be
- assigned by IETF consensus (RFCs). Examples include `3des-cbc',
- `sha-1', `hmac-sha1', and `zlib' (the quotes are not part of the
- name). Names of this format MUST NOT be used without first
- registering them. Registered names MUST NOT contain an at-sign
- (@) or a comma (,).
- o Anyone can define additional algorithms by using names in the
- format name@domainname, e.g. "[email protected]". The
- format of the part preceding the at sign is not specified; it MUST
- consist of US-ASCII characters except at-sign and comma. The part
- following the at-sign MUST be a valid fully qualified internet
- domain name [RFC-1034] controlled by the person or organization
- defining the name. It is up to each domain how it manages its
- local namespace.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-7. Message Numbers
-
- SSH packets have message numbers in the range 1 to 255. These numbers
- have been allocated as follows:
-
-
- Transport layer protocol:
-
- 1 to 19 Transport layer generic (e.g. disconnect, ignore, debug,
- etc.)
- 20 to 29 Algorithm negotiation
- 30 to 49 Key exchange method specific (numbers can be reused for
- different authentication methods)
-
- User authentication protocol:
-
- 50 to 59 User authentication generic
- 60 to 79 User authentication method specific (numbers can be
- reused for different authentication methods)
-
- Connection protocol:
-
- 80 to 89 Connection protocol generic
- 90 to 127 Channel related messages
-
- Reserved for client protocols:
-
- 128 to 191 Reserved
-
- Local extensions:
-
- 192 to 255 Local extensions
-
-
-
-8. IANA Considerations
-
- The initial state of the IANA registry is detailed in [SSH-NUMBERS].
-
- Allocation of the following types of names in the SSH protocols is
- assigned by IETF consensus:
- o SSH encryption algorithm names,
- o SSH MAC algorithm names,
- o SSH public key algorithm names (public key algorithm also implies
- encoding and signature/encryption capability),
- o SSH key exchange method names, and
- o SSH protocol (service) names.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- These names MUST be printable US-ASCII strings, and MUST NOT contain
- the characters at-sign ('@'), comma (','), or whitespace or control
- characters (ASCII codes 32 or less). Names are case-sensitive, and
- MUST NOT be longer than 64 characters.
-
- Names with the at-sign ('@') in them are allocated by the owner of
- DNS name after the at-sign (hierarchical allocation in [RFC-2343]),
- otherwise the same restrictions as above.
-
- Each category of names listed above has a separate namespace.
- However, using the same name in multiple categories SHOULD be avoided
- to minimize confusion.
-
- Message numbers (see Section Message Numbers (Section 7)) in the
- range of 0..191 are allocated via IETF consensus; message numbers in
- the 192..255 range (the "Local extensions" set) are reserved for
- private use.
-
-9. Security Considerations
-
- In order to make the entire body of Security Considerations more
- accessible, Security Considerations for the transport,
- authentication, and connection documents have been gathered here.
-
- The transport protocol [1] provides a confidential channel over an
- insecure network. It performs server host authentication, key
- exchange, encryption, and integrity protection. It also derives a
- unique session id that may be used by higher-level protocols.
-
- The authentication protocol [2] provides a suite of mechanisms which
- can be used to authenticate the client user to the server.
- Individual mechanisms specified in the in authentication protocol use
- the session id provided by the transport protocol and/or depend on
- the security and integrity guarantees of the transport protocol.
-
- The connection protocol [3] specifies a mechanism to multiplex
- multiple streams [channels] of data over the confidential and
- authenticated transport. It also specifies channels for accessing an
- interactive shell, for 'proxy-forwarding' various external protocols
- over the secure transport (including arbitrary TCP/IP protocols), and
- for accessing secure 'subsystems' on the server host.
-
-9.1 Pseudo-Random Number Generation
-
- This protocol binds each session key to the session by including
- random, session specific data in the hash used to produce session
- keys. Special care should be taken to ensure that all of the random
- numbers are of good quality. If the random data here (e.g., DH
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- parameters) are pseudo-random then the pseudo-random number generator
- should be cryptographically secure (i.e., its next output not easily
- guessed even when knowing all previous outputs) and, furthermore,
- proper entropy needs to be added to the pseudo-random number
- generator. RFC 1750 [1750] offers suggestions for sources of random
- numbers and entropy. Implementors should note the importance of
- entropy and the well-meant, anecdotal warning about the difficulty in
- properly implementing pseudo-random number generating functions.
-
- The amount of entropy available to a given client or server may
- sometimes be less than what is required. In this case one must
- either resort to pseudo-random number generation regardless of
- insufficient entropy or refuse to run the protocol. The latter is
- preferable.
-
-9.2 Transport
-
-9.2.1 Confidentiality
-
- It is beyond the scope of this document and the Secure Shell Working
- Group to analyze or recommend specific ciphers other than the ones
- which have been established and accepted within the industry. At the
- time of this writing, ciphers commonly in use include 3DES, ARCFOUR,
- twofish, serpent and blowfish. AES has been accepted by The
- published as a US Federal Information Processing Standards [FIPS-197]
- and the cryptographic community as being acceptable for this purpose
- as well has accepted AES. As always, implementors and users should
- check current literature to ensure that no recent vulnerabilities
- have been found in ciphers used within products. Implementors should
- also check to see which ciphers are considered to be relatively
- stronger than others and should recommend their use to users over
- relatively weaker ciphers. It would be considered good form for an
- implementation to politely and unobtrusively notify a user that a
- stronger cipher is available and should be used when a weaker one is
- actively chosen.
-
- The "none" cipher is provided for debugging and SHOULD NOT be used
- except for that purpose. It's cryptographic properties are
- sufficiently described in RFC 2410, which will show that its use does
- not meet the intent of this protocol.
-
- The relative merits of these and other ciphers may also be found in
- current literature. Two references that may provide information on
- the subject are [SCHNEIER] and [KAUFMAN,PERLMAN,SPECINER]. Both of
- these describe the CBC mode of operation of certain ciphers and the
- weakness of this scheme. Essentially, this mode is theoretically
- vulnerable to chosen cipher-text attacks because of the high
- predictability of the start of packet sequence. However, this attack
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- is still deemed difficult and not considered fully practicable
- especially if relatively longer block sizes are used.
-
- Additionally, another CBC mode attack may be mitigated through the
- insertion of packets containing SSH_MSG_IGNORE. Without this
- technique, a specific attack may be successful. For this attack
- (commonly known as the Rogaway attack
- [ROGAWAY],[DAI],[BELLARE,KOHNO,NAMPREMPRE]) to work, the attacker
- would need to know the IV of the next block that is going to be
- encrypted. In CBC mode that is the output of the encryption of the
- previous block. If the attacker does not have any way to see the
- packet yet (i.e it is in the internal buffers of the ssh
- implementation or even in the kernel) then this attack will not work.
- If the last packet has been sent out to the network (i.e the attacker
- has access to it) then he can use the attack.
-
- In the optimal case an implementor would need to add an extra packet
- only if the packet has been sent out onto the network and there are
- no other packets waiting for transmission. Implementors may wish to
- check to see if there are any unsent packets awaiting transmission,
- but unfortunately it is not normally easy to obtain this information
- from the kernel or buffers. If there are not, then a packet
- containing SSH_MSG_IGNORE SHOULD be sent. If a new packet is added
- to the stream every time the attacker knows the IV that is supposed
- to be used for the next packet, then the attacker will not be able to
- guess the correct IV, thus the attack will never be successfull.
-
- As an example, consider the following case:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains Record 1
-
- [500 ms passes, no ACK]
-
- TCP(seq=x, len=1000) ->
- contains Records 1,2
-
- ACK
-
-
- 1. The Nagle algorithm + TCP retransmits mean that the two records
- get coalesced into a single TCP segment
- 2. Record 2 is *not* at the beginning of the TCP segment and never
- will be, since it gets ACKed.
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- 3. Yet, the attack is possible because Record 1 has already been
- seen.
-
- As this example indicates, it's totally unsafe to use the existence
- of unflushed data in the TCP buffers proper as a guide to whether you
- need an empty packet, since when you do the second write(), the
- buffers will contain the un-ACKed Record 1.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- On the other hand, it's perfectly safe to have the following
- situation:
-
-
- Client Server
- ------ ------
- TCP(seq=x, len=500) ->
- contains SSH_MSG_IGNORE
-
- TCP(seq=y, len=500) ->
- contains Data
-
- Provided that the IV for second SSH Record is fixed after the data for
- the Data packet is determined -i.e. you do:
- read from user
- encrypt null packet
- encrypt data packet
-
-
-9.2.2 Data Integrity
-
- This protocol does allow the Data Integrity mechanism to be disabled.
- Implementors SHOULD be wary of exposing this feature for any purpose
- other than debugging. Users and administrators SHOULD be explicitly
- warned anytime the "none" MAC is enabled.
-
- So long as the "none" MAC is not used, this protocol provides data
- integrity.
-
- Because MACs use a 32 bit sequence number, they might start to leak
- information after 2**32 packets have been sent. However, following
- the rekeying recommendations should prevent this attack. The
- transport protocol [1] recommends rekeying after one gigabyte of
- data, and the smallest possible packet is 16 bytes. Therefore,
- rekeying SHOULD happen after 2**28 packets at the very most.
-
-9.2.3 Replay
-
- The use of a MAC other than 'none' provides integrity and
- authentication. In addition, the transport protocol provides a
- unique session identifier (bound in part to pseudo-random data that
- is part of the algorithm and key exchange process) that can be used
- by higher level protocols to bind data to a given session and prevent
- replay of data from prior sessions. For example, the authentication
- protocol uses this to prevent replay of signatures from previous
- sessions. Because public key authentication exchanges are
- cryptographically bound to the session (i.e., to the initial key
- exchange) they cannot be successfully replayed in other sessions.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Note that the session ID can be made public without harming the
- security of the protocol.
-
- If two session happen to have the same session ID [hash of key
- exchanges] then packets from one can be replayed against the other.
- It must be stressed that the chances of such an occurrence are,
- needless to say, minimal when using modern cryptographic methods.
- This is all the more so true when specifying larger hash function
- outputs and DH parameters.
-
- Replay detection using monotonically increasing sequence numbers as
- input to the MAC, or HMAC in some cases, is described in [RFC2085] />
- [RFC2246], [RFC2743], [RFC1964], [RFC2025], and [RFC1510]. The
- underlying construct is discussed in [RFC2104]. Essentially a
- different sequence number in each packet ensures that at least this
- one input to the MAC function will be unique and will provide a
- nonrecurring MAC output that is not predictable to an attacker. If
- the session stays active long enough, however, this sequence number
- will wrap. This event may provide an attacker an opportunity to
- replay a previously recorded packet with an identical sequence number
- but only if the peers have not rekeyed since the transmission of the
- first packet with that sequence number. If the peers have rekeyed,
- then the replay will be detected as the MAC check will fail. For
- this reason, it must be emphasized that peers MUST rekey before a
- wrap of the sequence numbers. Naturally, if an attacker does attempt
- to replay a captured packet before the peers have rekeyed, then the
- receiver of the duplicate packet will not be able to validate the MAC
- and it will be discarded. The reason that the MAC will fail is
- because the receiver will formulate a MAC based upon the packet
- contents, the shared secret, and the expected sequence number. Since
- the replayed packet will not be using that expected sequence number
- (the sequence number of the replayed packet will have already been
- passed by the receiver) then the calculated MAC will not match the
- MAC received with the packet.
-
-9.2.4 Man-in-the-middle
-
- This protocol makes no assumptions nor provisions for an
- infrastructure or means for distributing the public keys of hosts. It
- is expected that this protocol will sometimes be used without first
- verifying the association between the server host key and the server
- host name. Such usage is vulnerable to man-in-the-middle attacks.
- This section describes this and encourages administrators and users
- to understand the importance of verifying this association before any
- session is initiated.
-
- There are three cases of man-in-the-middle attacks to consider. The
- first is where an attacker places a device between the client and the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server before the session is initiated. In this case, the attack
- device is trying to mimic the legitimate server and will offer its
- public key to the client when the client initiates a session. If it
- were to offer the public key of the server, then it would not be able
- to decrypt or sign the transmissions between the legitimate server
- and the client unless it also had access to the private-key of the
- host. The attack device will also, simultaneously to this, initiate
- a session to the legitimate server masquerading itself as the client.
- If the public key of the server had been securely distributed to the
- client prior to that session initiation, the key offered to the
- client by the attack device will not match the key stored on the
- client. In that case, the user SHOULD be given a warning that the
- offered host key does not match the host key cached on the client.
- As described in Section 3.1 of [ARCH], the user may be free to accept
- the new key and continue the session. It is RECOMMENDED that the
- warning provide sufficient information to the user of the client
- device so they may make an informed decision. If the user chooses to
- continue the session with the stored public-key of the server (not
- the public-key offered at the start of the session), then the session
- specific data between the attacker and server will be different
- between the client-to-attacker session and the attacker-to-server
- sessions due to the randomness discussed above. From this, the
- attacker will not be able to make this attack work since the attacker
- will not be able to correctly sign packets containing this session
- specific data from the server since he does not have the private key
- of that server.
-
- The second case that should be considered is similar to the first
- case in that it also happens at the time of connection but this case
- points out the need for the secure distribution of server public
- keys. If the server public keys are not securely distributed then
- the client cannot know if it is talking to the intended server. An
- attacker may use social engineering techniques to pass off server
- keys to unsuspecting users and may then place a man-in-the-middle
- attack device between the legitimate server and the clients. If this
- is allowed to happen then the clients will form client-to-attacker
- sessions and the attacker will form attacker-to-server sessions and
- will be able to monitor and manipulate all of the traffic between the
- clients and the legitimate servers. Server administrators are
- encouraged to make host key fingerprints available for checking by
- some means whose security does not rely on the integrity of the
- actual host keys. Possible mechanisms are discussed in Section 3.1
- of [SSH-ARCH] and may also include secured Web pages, physical pieces
- of paper, etc. Implementors SHOULD provide recommendations on how
- best to do this with their implementation. Because the protocol is
- extensible, future extensions to the protocol may provide better
- mechanisms for dealing with the need to know the server's host key
- before connecting. For example, making the host key fingerprint
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- available through a secure DNS lookup, or using kerberos over gssapi
- during key exchange to authenticate the server are possibilities.
-
- In the third man-in-the-middle case, attackers may attempt to
- manipulate packets in transit between peers after the session has
- been established. As described in the Replay part of this section, a
- successful attack of this nature is very improbable. As in the
- Replay section, this reasoning does assume that the MAC is secure and
- that it is infeasible to construct inputs to a MAC algorithm to give
- a known output. This is discussed in much greater detail in Section
- 6 of RFC 2104. If the MAC algorithm has a vulnerability or is weak
- enough, then the attacker may be able to specify certain inputs to
- yield a known MAC. With that they may be able to alter the contents
- of a packet in transit. Alternatively the attacker may be able to
- exploit the algorithm vulnerability or weakness to find the shared
- secret by reviewing the MACs from captured packets. In either of
- those cases, an attacker could construct a packet or packets that
- could be inserted into an SSH stream. To prevent that, implementors
- are encouraged to utilize commonly accepted MAC algorithms and
- administrators are encouraged to watch current literature and
- discussions of cryptography to ensure that they are not using a MAC
- algorithm that has a recently found vulnerability or weakness.
-
- In summary, the use of this protocol without a reliable association
- of the binding between a host and its host keys is inherently
- insecure and is NOT RECOMMENDED. It may however be necessary in
- non-security critical environments, and will still provide protection
- against passive attacks. Implementors of protocols and applications
- running on top of this protocol should keep this possibility in mind.
-
-9.2.5 Denial-of-service
-
- This protocol is designed to be used over a reliable transport. If
- transmission errors or message manipulation occur, the connection is
- closed. The connection SHOULD be re-established if this occurs.
- Denial of service attacks of this type ("wire cutter") are almost
- impossible to avoid.
-
- In addition, this protocol is vulnerable to Denial of Service attacks
- because an attacker can force the server to go through the CPU and
- memory intensive tasks of connection setup and key exchange without
- authenticating. Implementors SHOULD provide features that make this
- more difficult. For example, only allowing connections from a subset
- of IPs known to have valid users.
-
-9.2.6 Covert Channels
-
- The protocol was not designed to eliminate covert channels. For
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- example, the padding, SSH_MSG_IGNORE messages, and several other
- places in the protocol can be used to pass covert information, and
- the recipient has no reliable way to verify whether such information
- is being sent.
-
-9.2.7 Forward Secrecy
-
- It should be noted that the Diffie-Hellman key exchanges may provide
- perfect forward secrecy (PFS). PFS is essentially defined as the
- cryptographic property of a key-establishment protocol in which the
- compromise of a session key or long-term private key after a given
- session does not cause the compromise of any earlier session. [ANSI
- T1.523-2001] SSHv2 sessions resulting from a key exchange using
- diffie-hellman-group1-sha1 are secure even if private keying/
- authentication material is later revealed, but not if the session
- keys are revealed. So, given this definition of PFS, SSHv2 does have
- PFS. It is hoped that all other key exchange mechanisms proposed and
- used in the future will also provide PFS. This property is not
- commuted to any of the applications or protocols using SSH as a
- transport however. The transport layer of SSH provides
- confidentiality for password authentication and other methods that
- rely on secret data.
-
- Of course, if the DH private parameters for the client and server are
- revealed then the session key is revealed, but these items can be
- thrown away after the key exchange completes. It's worth pointing
- out that these items should not be allowed to end up on swap space
- and that they should be erased from memory as soon as the key
- exchange completes.
-
-9.3 Authentication Protocol
-
- The purpose of this protocol is to perform client user
- authentication. It assumes that this run over a secure transport
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session.
-
- Several authentication methods with different security
- characteristics are allowed. It is up to the server's local policy
- to decide which methods (or combinations of methods) it is willing to
- accept for each user. Authentication is no stronger than the weakest
- combination allowed.
-
- The server may go into a "sleep" period after repeated unsuccessful
- authentication attempts to make key search more difficult for
- attackers. Care should be taken so that this doesn't become a
- self-denial of service vector.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-9.3.1 Weak Transport
-
- If the transport layer does not provide confidentiality,
- authentication methods that rely on secret data SHOULD be disabled.
- If it does not provide strong integrity protection, requests to
- change authentication data (e.g. a password change) SHOULD be
- disabled to prevent an attacker from modifying the ciphertext
- without being noticed, or rendering the new authentication data
- unusable (denial of service).
-
- The assumption as stated above that the Authentication Protocol only
- run over a secure transport that has previously authenticated the
- server is very important to note. People deploying SSH are reminded
- of the consequences of man-in-the-middle attacks if the client does
- not have a very strong a priori association of the server with the
- host key of that server. Specifically for the case of the
- Authentication Protocol the client may form a session to a
- man-in-the-middle attack device and divulge user credentials such as
- their username and password. Even in the cases of authentication
- where no user credentials are divulged, an attacker may still gain
- information they shouldn't have by capturing key-strokes in much the
- same way that a honeypot works.
-
-9.3.2 Debug messages
-
- Special care should be taken when designing debug messages. These
- messages may reveal surprising amounts of information about the host
- if not properly designed. Debug messages can be disabled (during
- user authentication phase) if high security is required.
- Administrators of host machines should make all attempts to
- compartmentalize all event notification messages and protect them
- from unwarranted observation. Developers should be aware of the
- sensitive nature of some of the normal event messages and debug
- messages and may want to provide guidance to administrators on ways
- to keep this information away from unauthorized people. Developers
- should consider minimizing the amount of sensitive information
- obtainable by users during the authentication phase in accordance
- with the local policies. For this reason, it is RECOMMENDED that
- debug messages be initially disabled at the time of deployment and
- require an active decision by an administrator to allow them to be
- enabled. It is also RECOMMENDED that a message expressing this
- concern be presented to the administrator of a system when the action
- is taken to enable debugging messages.
-
-9.3.3 Local security policy
-
- Implementer MUST ensure that the credentials provided validate the
- professed user and also MUST ensure that the local policy of the
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- server permits the user the access requested. In particular, because
- of the flexible nature of the SSH connection protocol, it may not be
- possible to determine the local security policy, if any, that should
- apply at the time of authentication because the kind of service being
- requested is not clear at that instant. For example, local policy
- might allow a user to access files on the server, but not start an
- interactive shell. However, during the authentication protocol, it is
- not known whether the user will be accessing files or attempting to
- use an interactive shell, or even both. In any event, where local
- security policy for the server host exists, it MUST be applied and
- enforced correctly.
-
- Implementors are encouraged to provide a default local policy and
- make its parameters known to administrators and users. At the
- discretion of the implementors, this default policy may be along the
- lines of 'anything goes' where there are no restrictions placed upon
- users, or it may be along the lines of 'excessively restrictive' in
- which case the administrators will have to actively make changes to
- this policy to meet their needs. Alternatively, it may be some
- attempt at providing something practical and immediately useful to
- the administrators of the system so they don't have to put in much
- effort to get SSH working. Whatever choice is made MUST be applied
- and enforced as required above.
-
-9.3.4 Public key authentication
-
- The use of public-key authentication assumes that the client host has
- not been compromised. It also assumes that the private-key of the
- server host has not been compromised.
-
- This risk can be mitigated by the use of passphrases on private keys;
- however, this is not an enforceable policy. The use of smartcards,
- or other technology to make passphrases an enforceable policy is
- suggested.
-
- The server could require both password and public-key authentication,
- however, this requires the client to expose its password to the
- server (see section on password authentication below.)
-
-9.3.5 Password authentication
-
- The password mechanism as specified in the authentication protocol
- assumes that the server has not been compromised. If the server has
- been compromised, using password authentication will reveal a valid
- username / password combination to the attacker, which may lead to
- further compromises.
-
- This vulnerability can be mitigated by using an alternative form of
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- authentication. For example, public-key authentication makes no
- assumptions about security on the server.
-
-9.3.6 Host based authentication
-
- Host based authentication assumes that the client has not been
- compromised. There are no mitigating strategies, other than to use
- host based authentication in combination with another authentication
- method.
-
-9.4 Connection protocol
-
-9.4.1 End point security
-
- End point security is assumed by the connection protocol. If the
- server has been compromised, any terminal sessions, port forwarding,
- or systems accessed on the host are compromised. There are no
- mitigating factors for this.
-
- If the client end point has been compromised, and the server fails to
- stop the attacker at the authentication protocol, all services
- exposed (either as subsystems or through forwarding) will be
- vulnerable to attack. Implementors SHOULD provide mechanisms for
- administrators to control which services are exposed to limit the
- vulnerability of other services.
-
- These controls might include controlling which machines and ports can
- be target in 'port-forwarding' operations, which users are allowed to
- use interactive shell facilities, or which users are allowed to use
- exposed subsystems.
-
-9.4.2 Proxy forwarding
-
- The SSH connection protocol allows for proxy forwarding of other
- protocols such as SNMP, POP3, and HTTP. This may be a concern for
- network administrators who wish to control the access of certain
- applications by users located outside of their physical location.
- Essentially, the forwarding of these protocols may violate site
- specific security policies as they may be undetectably tunneled
- through a firewall. Implementors SHOULD provide an administrative
- mechanism to control the proxy forwarding functionality so that site
- specific security policies may be upheld.
-
- In addition, a reverse proxy forwarding functionality is available,
- which again can be used to bypass firewall controls.
-
- As indicated above, end-point security is assumed during proxy
- forwarding operations. Failure of end-point security will compromise
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- all data passed over proxy forwarding.
-
-9.4.3 X11 forwarding
-
- Another form of proxy forwarding provided by the ssh connection
- protocol is the forwarding of the X11 protocol. If end-point
- security has been compromised, X11 forwarding may allow attacks
- against the X11 server. Users and administrators should, as a matter
- of course, use appropriate X11 security mechanisms to prevent
- unauthorized use of the X11 server. Implementors, administrators and
- users who wish to further explore the security mechanisms of X11 are
- invited to read [SCHEIFLER] and analyze previously reported problems
- with the interactions between SSH forwarding and X11 in CERT
- vulnerabilities VU#363181 and VU#118892 [CERT].
-
- X11 display forwarding with SSH, by itself, is not sufficient to
- correct well known problems with X11 security [VENEMA]. However, X11
- display forwarding in SSHv2 (or other, secure protocols), combined
- with actual and pseudo-displays which accept connections only over
- local IPC mechanisms authorized by permissions or ACLs, does correct
- many X11 security problems as long as the "none" MAC is not used. It
- is RECOMMENDED that X11 display implementations default to allowing
- display opens only over local IPC. It is RECOMMENDED that SSHv2
- server implementations that support X11 forwarding default to
- allowing display opens only over local IPC. On single-user systems
- it might be reasonable to default to allowing local display opens
- over TCP/IP.
-
- Implementors of the X11 forwarding protocol SHOULD implement the
- magic cookie access checking spoofing mechanism as described in
- [ssh-connect] as an additional mechanism to prevent unauthorized use
- of the proxy.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- National Institue of Standards and Technology, "FIPS 197,
- Specification for the Advanced Encryption Standard",
- November 2001.
-
- [ANSI T1.523-2001]
- American National Standards Insitute, Inc., "Telecom
- Glossary 2000", February 2001.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [RFC0854] Postel, J. and J. Reynolds, "Telnet Protocol
- Specification", STD 8, RFC 854, May 1983.
-
- [RFC0894] Hornig, C., "Standard for the transmission of IP datagrams
- over Ethernet networks", STD 41, RFC 894, April 1984.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
- STD 13, RFC 1034, November 1987.
-
- [RFC1134] Perkins, D., "Point-to-Point Protocol: A proposal for
- multi-protocol transmission of datagrams over
- Point-to-Point links", RFC 1134, November 1989.
-
- [RFC1282] Kantor, B., "BSD Rlogin", RFC 1282, December 1991.
-
- [RFC1510] Kohl, J. and B. Neuman, "The Kerberos Network
- Authentication Service (V5)", RFC 1510, September 1993.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- [RFC1700] Reynolds, J. and J. Postel, "Assigned Numbers", RFC 1700,
- October 1994.
-
- [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
- Recommendations for Security", RFC 1750, December 1994.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC
- 1964, June 1996.
-
- [RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism
- (SPKM)", RFC 2025, October 1996.
-
- [RFC2085] Oehler, M. and R. Glenn, "HMAC-MD5 IP Authentication with
- Replay Prevention", RFC 2085, February 1997.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2246] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A.
- and P. Kocher, "The TLS Protocol Version 1.0", RFC 2246,
- January 1999.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2410] Glenn, R. and S. Kent, "The NULL Encryption Algorithm and
- Its Use With IPsec", RFC 2410, November 1998.
-
- [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
- IANA Considerations Section in RFCs", BCP 26, RFC 2434,
- October 1998.
-
- [RFC2743] Linn, J., "Generic Security Service Application Program
- Interface Version 2, Update 1", RFC 2743, January 2000.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [KAUFMAN,PERLMAN,SPECINER]
- Kaufman, C., Perlman, R. and M. Speciner, "Network
- Security: PRIVATE Communication in a PUBLIC World", 1995.
-
- [CERT] CERT Coordination Center, The., "http://www.cert.org/nav/
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- index_red.html".
-
- [VENEMA] Venema, W., "Murphy's Law and Computer Security",
- Proceedings of 6th USENIX Security Symposium, San Jose CA
- http://www.usenix.org/publications/library/proceedings/
- sec96/venema.html, July 1996.
-
- [ROGAWAY] Rogaway, P., "Problems with Proposed IP Cryptography",
- Unpublished paper http://www.cs.ucdavis.edu/~rogaway/
- papers/draft-rogaway-ipsec-comments-00.txt, 1996.
-
- [DAI] Dai, W., "An attack against SSH2 protocol", Email to the
- SECSH Working Group [email protected] ftp://
- ftp.ietf.org/ietf-mail-archive/secsh/2002-02.mail, Feb
- 2002.
-
- [BELLARE,KOHNO,NAMPREMPRE]
- Bellaire, M., Kohno, T. and C. Namprempre, "Authenticated
- Encryption in SSH: Fixing the SSH Binary Packet Protocol",
- , Sept 2002.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Protocol Architecture Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
deleted file mode 100644
index 7a386724c2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.2.ps
+++ /dev/null
@@ -1,2557 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:33:02 2003
-%%Orientation: Portrait
-%%Pages: 11 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Connection Protocol) s
-5 613 M
-( draft-ietf-secsh-connect-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH Connection Protocol. It provides) s
-5 239 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 228 M
-( TCP/IP connections, and forwarded X11 connections. All of these) s
-5 217 M
-( channels are multiplexed into a single encrypted tunnel.) s
-5 195 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 184 M
-( SSH transport layer and user authentication protocols.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 624 M
-( 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4) s
-5 602 M
-( 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5) s
-5 591 M
-( 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6) s
-5 580 M
-( 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8) s
-5 558 M
-( 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8) s
-5 547 M
-( 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8) s
-5 536 M
-( 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 525 M
-( 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9) s
-5 514 M
-( 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 503 M
-( 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10) s
-5 492 M
-( 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10) s
-5 481 M
-( 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11) s
-5 470 M
-( 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12) s
-5 459 M
-( 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12) s
-5 448 M
-( 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12) s
-5 437 M
-( 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13) s
-5 426 M
-( 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14) s
-5 415 M
-( 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14) s
-5 404 M
-( 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15) s
-5 393 M
-( 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16) s
-5 382 M
-( 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 10. Security Considerations . . . . . . . . . . . . . . . . . . 18) s
-5 360 M
-( 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19) s
-5 349 M
-( 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19) s
-5 338 M
-( Normative References . . . . . . . . . . . . . . . . . . . . 19) s
-5 327 M
-( Informative References . . . . . . . . . . . . . . . . . . . 20) s
-5 316 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20) s
-5 305 M
-( Intellectual Property and Copyright Statements . . . . . . . 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH Connection Protocol has been designed to run on top of the) s
-5 536 M
-( SSH transport layer and user authentication protocols. It provides) s
-5 525 M
-( interactive login sessions, remote execution of commands, forwarded) s
-5 514 M
-( TCP/IP connections, and forwarded X11 connections. The service name) s
-5 503 M
-( for this protocol is "ssh-connection".) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-(3. Conventions Used in This Document) s
-5 404 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 393 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 382 M
-( described in [RFC2119].) s
-5 360 M
-( The used data types and terminology are specified in the architecture) s
-5 349 M
-( document [SSH-ARCH].) s
-5 327 M
-( The architecture document also discusses the algorithm naming) s
-5 316 M
-( conventions that MUST be used with the SSH protocols.) s
-5 294 M
-(4. Global Requests) s
-5 272 M
-( There are several kinds of requests that affect the state of the) s
-5 261 M
-( remote end "globally", independent of any channels. An example is a) s
-5 250 M
-( request to start TCP/IP forwarding for a specific port. All such) s
-5 239 M
-( requests use the following format.) s
-5 217 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 206 M
-( string request name \(restricted to US-ASCII\)) s
-5 195 M
-( boolean want reply) s
-5 184 M
-( ... request-specific data follows) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( Request names follow the DNS extensibility naming convention outlined) s
-5 679 M
-( in [SSH-ARCH].) s
-5 657 M
-( The recipient will respond to this message with) s
-5 646 M
-( SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is) s
-5 635 M
-( TRUE.) s
-5 613 M
-( byte SSH_MSG_REQUEST_SUCCESS) s
-5 602 M
-( ..... response specific data) s
-5 580 M
-( Usually the response specific data is non-existent.) s
-5 558 M
-( If the recipient does not recognize or support the request, it simply) s
-5 547 M
-( responds with SSH_MSG_REQUEST_FAILURE.) s
-5 525 M
-( byte SSH_MSG_REQUEST_FAILURE) s
-5 492 M
-(5. Channel Mechanism) s
-5 470 M
-( All terminal sessions, forwarded connections, etc. are channels.) s
-5 459 M
-( Either side may open a channel. Multiple channels are multiplexed) s
-5 448 M
-( into a single connection.) s
-5 426 M
-( Channels are identified by numbers at each end. The number referring) s
-5 415 M
-( to a channel may be different on each side. Requests to open a) s
-5 404 M
-( channel contain the sender's channel number. Any other) s
-5 393 M
-( channel-related messages contain the recipient's channel number for) s
-5 382 M
-( the channel.) s
-5 360 M
-( Channels are flow-controlled. No data may be sent to a channel until) s
-5 349 M
-( a message is received to indicate that window space is available.) s
-5 327 M
-(5.1 Opening a Channel) s
-5 305 M
-( When either side wishes to open a new channel, it allocates a local) s
-5 294 M
-( number for the channel. It then sends the following message to the) s
-5 283 M
-( other side, and includes the local channel number and initial window) s
-5 272 M
-( size in the message.) s
-5 250 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 239 M
-( string channel type \(restricted to US-ASCII\)) s
-5 228 M
-( uint32 sender channel) s
-5 217 M
-( uint32 initial window size) s
-5 206 M
-( uint32 maximum packet size) s
-5 195 M
-( ... channel type specific data follows) s
-5 173 M
-( The channel type is a name as described in the SSH architecture) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( document, with similar extension mechanisms. `sender channel' is a) s
-5 679 M
-( local identifier for the channel used by the sender of this message.) s
-5 668 M
-( `initial window size' specifies how many bytes of channel data can be) s
-5 657 M
-( sent to the sender of this message without adjusting the window.) s
-5 646 M
-( `Maximum packet size' specifies the maximum size of an individual) s
-5 635 M
-( data packet that can be sent to the sender \(for example, one might) s
-5 624 M
-( want to use smaller packets for interactive connections to get better) s
-5 613 M
-( interactive response on slow links\).) s
-5 591 M
-( The remote side then decides whether it can open the channel, and) s
-5 580 M
-( responds with either) s
-5 558 M
-( byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 547 M
-( uint32 recipient channel) s
-5 536 M
-( uint32 sender channel) s
-5 525 M
-( uint32 initial window size) s
-5 514 M
-( uint32 maximum packet size) s
-5 503 M
-( ... channel type specific data follows) s
-5 481 M
-( where `recipient channel' is the channel number given in the original) s
-5 470 M
-( open request, and `sender channel' is the channel number allocated by) s
-5 459 M
-( the other side, or) s
-5 437 M
-( byte SSH_MSG_CHANNEL_OPEN_FAILURE) s
-5 426 M
-( uint32 recipient channel) s
-5 415 M
-( uint32 reason code) s
-5 404 M
-( string additional textual information \(ISO-10646 UTF-8 [RFC2279]\)) s
-5 393 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 371 M
-( If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support) s
-5 360 M
-( the specified channel type, it simply responds with) s
-5 349 M
-( SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional) s
-5 338 M
-( information to the user. If this is done, the client software should) s
-5 327 M
-( take the precautions discussed in [SSH-ARCH].) s
-5 305 M
-( The following reason codes are defined:) s
-5 283 M
-( #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1) s
-5 272 M
-( #define SSH_OPEN_CONNECT_FAILED 2) s
-5 261 M
-( #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3) s
-5 250 M
-( #define SSH_OPEN_RESOURCE_SHORTAGE 4) s
-5 217 M
-(5.2 Data Transfer) s
-5 195 M
-( The window size specifies how many bytes the other party can send) s
-5 184 M
-( before it must wait for the window to be adjusted. Both parties use) s
-5 173 M
-( the following message to adjust the window.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_CHANNEL_WINDOW_ADJUST) s
-5 679 M
-( uint32 recipient channel) s
-5 668 M
-( uint32 bytes to add) s
-5 646 M
-( After receiving this message, the recipient MAY send the given number) s
-5 635 M
-( of bytes more than it was previously allowed to send; the window size) s
-5 624 M
-( is incremented.) s
-5 602 M
-( Data transfer is done with messages of the following type.) s
-5 580 M
-( byte SSH_MSG_CHANNEL_DATA) s
-5 569 M
-( uint32 recipient channel) s
-5 558 M
-( string data) s
-5 536 M
-( The maximum amount of data allowed is the current window size. The) s
-5 525 M
-( window size is decremented by the amount of data sent. Both parties) s
-5 514 M
-( MAY ignore all extra data sent after the allowed window is empty.) s
-5 492 M
-( Additionally, some channels can transfer several types of data. An) s
-5 481 M
-( example of this is stderr data from interactive sessions. Such data) s
-5 470 M
-( can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a) s
-5 459 M
-( separate integer specifies the type of the data. The available types) s
-5 448 M
-( and their interpretation depend on the type of the channel.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_EXTENDED_DATA) s
-5 415 M
-( uint32 recipient_channel) s
-5 404 M
-( uint32 data_type_code) s
-5 393 M
-( string data) s
-5 371 M
-( Data sent with these messages consumes the same window as ordinary) s
-5 360 M
-( data.) s
-5 338 M
-( Currently, only the following type is defined.) s
-5 316 M
-( #define SSH_EXTENDED_DATA_STDERR 1) s
-5 283 M
-(5.3 Closing a Channel) s
-5 261 M
-( When a party will no longer send more data to a channel, it SHOULD) s
-5 250 M
-( send SSH_MSG_CHANNEL_EOF.) s
-5 228 M
-( byte SSH_MSG_CHANNEL_EOF) s
-5 217 M
-( uint32 recipient_channel) s
-5 195 M
-( No explicit response is sent to this message; however, the) s
-5 184 M
-( application may send EOF to whatever is at the other end of the) s
-5 173 M
-( channel. Note that the channel remains open after this message, and) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( more data may still be sent in the other direction. This message) s
-5 679 M
-( does not consume window space and can be sent even if no window space) s
-5 668 M
-( is available.) s
-5 646 M
-( When either party wishes to terminate the channel, it sends) s
-5 635 M
-( SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST) s
-5 624 M
-( send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this) s
-5 613 M
-( message for the channel. The channel is considered closed for a) s
-5 602 M
-( party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and) s
-5 591 M
-( the party may then reuse the channel number. A party MAY send) s
-5 580 M
-( SSH_MSG_CHANNEL_CLOSE without having sent or received) s
-5 569 M
-( SSH_MSG_CHANNEL_EOF.) s
-5 547 M
-( byte SSH_MSG_CHANNEL_CLOSE) s
-5 536 M
-( uint32 recipient_channel) s
-5 514 M
-( This message does not consume window space and can be sent even if no) s
-5 503 M
-( window space is available.) s
-5 481 M
-( It is recommended that any data sent before this message is delivered) s
-5 470 M
-( to the actual destination, if possible.) s
-5 448 M
-(5.4 Channel-Specific Requests) s
-5 426 M
-( Many channel types have extensions that are specific to that) s
-5 415 M
-( particular channel type. An example is requesting a pty \(pseudo) s
-5 404 M
-( terminal\) for an interactive session.) s
-5 382 M
-( All channel-specific requests use the following format.) s
-5 360 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 349 M
-( uint32 recipient channel) s
-5 338 M
-( string request type \(restricted to US-ASCII\)) s
-5 327 M
-( boolean want reply) s
-5 316 M
-( ... type-specific data) s
-5 294 M
-( If want reply is FALSE, no response will be sent to the request.) s
-5 283 M
-( Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS) s
-5 272 M
-( or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation) s
-5 261 M
-( messages. If the request is not recognized or is not supported for) s
-5 250 M
-( the channel, SSH_MSG_CHANNEL_FAILURE is returned.) s
-5 228 M
-( This message does not consume window space and can be sent even if no) s
-5 217 M
-( window space is available. Request types are local to each channel) s
-5 206 M
-( type.) s
-5 184 M
-( The client is allowed to send further messages without waiting for) s
-5 173 M
-( the response to the request.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( request type names follow the DNS extensibility naming convention) s
-5 679 M
-( outlined in [SSH-ARCH]) s
-5 657 M
-( byte SSH_MSG_CHANNEL_SUCCESS) s
-5 646 M
-( uint32 recipient_channel) s
-5 613 M
-( byte SSH_MSG_CHANNEL_FAILURE) s
-5 602 M
-( uint32 recipient_channel) s
-5 580 M
-( These messages do not consume window space and can be sent even if no) s
-5 569 M
-( window space is available.) s
-5 547 M
-(6. Interactive Sessions) s
-5 525 M
-( A session is a remote execution of a program. The program may be a) s
-5 514 M
-( shell, an application, a system command, or some built-in subsystem.) s
-5 503 M
-( It may or may not have a tty, and may or may not involve X11) s
-5 492 M
-( forwarding. Multiple sessions can be active simultaneously.) s
-5 470 M
-(6.1 Opening a Session) s
-5 448 M
-( A session is started by sending the following message.) s
-5 426 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 415 M
-( string "session") s
-5 404 M
-( uint32 sender channel) s
-5 393 M
-( uint32 initial window size) s
-5 382 M
-( uint32 maximum packet size) s
-5 360 M
-( Client implementations SHOULD reject any session channel open) s
-5 349 M
-( requests to make it more difficult for a corrupt server to attack the) s
-5 338 M
-( client.) s
-5 316 M
-(6.2 Requesting a Pseudo-Terminal) s
-5 294 M
-( A pseudo-terminal can be allocated for the session by sending the) s
-5 283 M
-( following message.) s
-5 261 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 250 M
-( uint32 recipient_channel) s
-5 239 M
-( string "pty-req") s
-5 228 M
-( boolean want_reply) s
-5 217 M
-( string TERM environment variable value \(e.g., vt100\)) s
-5 206 M
-( uint32 terminal width, characters \(e.g., 80\)) s
-5 195 M
-( uint32 terminal height, rows \(e.g., 24\)) s
-5 184 M
-( uint32 terminal width, pixels \(e.g., 640\)) s
-5 173 M
-( uint32 terminal height, pixels \(e.g., 480\)) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( string encoded terminal modes) s
-5 668 M
-( The encoding of terminal modes is described in Section Encoding of) s
-5 657 M
-( Terminal Modes \(Section 8\). Zero dimension parameters MUST be) s
-5 646 M
-( ignored. The character/row dimensions override the pixel dimensions) s
-5 635 M
-( \(when nonzero\). Pixel dimensions refer to the drawable area of the) s
-5 624 M
-( window.) s
-5 602 M
-( The dimension parameters are only informational.) s
-5 580 M
-( The client SHOULD ignore pty requests.) s
-5 558 M
-(6.3 X11 Forwarding) s
-5 536 M
-(6.3.1 Requesting X11 Forwarding) s
-5 514 M
-( X11 forwarding may be requested for a session by sending) s
-5 492 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 481 M
-( uint32 recipient channel) s
-5 470 M
-( string "x11-req") s
-5 459 M
-( boolean want reply) s
-5 448 M
-( boolean single connection) s
-5 437 M
-( string x11 authentication protocol) s
-5 426 M
-( string x11 authentication cookie) s
-5 415 M
-( uint32 x11 screen number) s
-5 393 M
-( It is recommended that the authentication cookie that is sent be a) s
-5 382 M
-( fake, random cookie, and that the cookie is checked and replaced by) s
-5 371 M
-( the real cookie when a connection request is received.) s
-5 349 M
-( X11 connection forwarding should stop when the session channel is) s
-5 338 M
-( closed; however, already opened forwardings should not be) s
-5 327 M
-( automatically closed when the session channel is closed.) s
-5 305 M
-( If `single connection' is TRUE, only a single connection should be) s
-5 294 M
-( forwarded. No more connections will be forwarded after the first, or) s
-5 283 M
-( after the session channel has been closed.) s
-5 261 M
-( The "x11 authentication protocol" is the name of the X11) s
-5 250 M
-( authentication method used, e.g. "MIT-MAGIC-COOKIE-1".) s
-5 228 M
-( The x11 authentication cookie MUST be hexadecimal encoded.) s
-5 206 M
-( X Protocol is documented in [SCHEIFLER].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.3.2 X11 Channels) s
-5 668 M
-( X11 channels are opened with a channel open request. The resulting) s
-5 657 M
-( channels are independent of the session, and closing the session) s
-5 646 M
-( channel does not close the forwarded X11 channels.) s
-5 624 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 613 M
-( string "x11") s
-5 602 M
-( uint32 sender channel) s
-5 591 M
-( uint32 initial window size) s
-5 580 M
-( uint32 maximum packet size) s
-5 569 M
-( string originator address \(e.g. "192.168.7.38"\)) s
-5 558 M
-( uint32 originator port) s
-5 536 M
-( The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION) s
-5 525 M
-( or SSH_MSG_CHANNEL_OPEN_FAILURE.) s
-5 503 M
-( Implementations MUST reject any X11 channel open requests if they) s
-5 492 M
-( have not requested X11 forwarding.) s
-5 470 M
-(6.4 Environment Variable Passing) s
-5 448 M
-( Environment variables may be passed to the shell/command to be) s
-5 437 M
-( started later. Uncontrolled setting of environment variables in a) s
-5 426 M
-( privileged process can be a security hazard. It is recommended that) s
-5 415 M
-( implementations either maintain a list of allowable variable names or) s
-5 404 M
-( only set environment variables after the server process has dropped) s
-5 393 M
-( sufficient privileges.) s
-5 371 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 360 M
-( uint32 recipient channel) s
-5 349 M
-( string "env") s
-5 338 M
-( boolean want reply) s
-5 327 M
-( string variable name) s
-5 316 M
-( string variable value) s
-5 283 M
-(6.5 Starting a Shell or a Command) s
-5 261 M
-( Once the session has been set up, a program is started at the remote) s
-5 250 M
-( end. The program can be a shell, an application program or a) s
-5 239 M
-( subsystem with a host-independent name. Only one of these requests) s
-5 228 M
-( can succeed per channel.) s
-5 206 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 195 M
-( uint32 recipient channel) s
-5 184 M
-( string "shell") s
-5 173 M
-( boolean want reply) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This message will request the user's default shell \(typically defined) s
-5 679 M
-( in /etc/passwd in UNIX systems\) to be started at the other end.) s
-5 657 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 646 M
-( uint32 recipient channel) s
-5 635 M
-( string "exec") s
-5 624 M
-( boolean want reply) s
-5 613 M
-( string command) s
-5 591 M
-( This message will request the server to start the execution of the) s
-5 580 M
-( given command. The command string may contain a path. Normal) s
-5 569 M
-( precautions MUST be taken to prevent the execution of unauthorized) s
-5 558 M
-( commands.) s
-5 536 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 525 M
-( uint32 recipient channel) s
-5 514 M
-( string "subsystem") s
-5 503 M
-( boolean want reply) s
-5 492 M
-( string subsystem name) s
-5 470 M
-( This last form executes a predefined subsystem. It is expected that) s
-5 459 M
-( these will include a general file transfer mechanism, and possibly) s
-5 448 M
-( other features. Implementations may also allow configuring more such) s
-5 437 M
-( mechanisms. As the user's shell is usually used to execute the) s
-5 426 M
-( subsystem, it is advisable for the subsystem protocol to have a) s
-5 415 M
-( "magic cookie" at the beginning of the protocol transaction to) s
-5 404 M
-( distinguish it from arbitrary output generated by shell) s
-5 393 M
-( initialization scripts etc. This spurious output from the shell may) s
-5 382 M
-( be filtered out either at the server or at the client.) s
-5 360 M
-( The server SHOULD not halt the execution of the protocol stack when) s
-5 349 M
-( starting a shell or a program. All input and output from these SHOULD) s
-5 338 M
-( be redirected to the channel or to the encrypted tunnel.) s
-5 316 M
-( It is RECOMMENDED to request and check the reply for these messages.) s
-5 305 M
-( The client SHOULD ignore these messages.) s
-5 283 M
-( Subsystem names follow the DNS extensibility naming convention) s
-5 272 M
-( outlined in [SSH-ARCH].) s
-5 250 M
-(6.6 Session Data Transfer) s
-5 228 M
-( Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and) s
-5 217 M
-( SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The) s
-5 206 M
-( extended data type SSH_EXTENDED_DATA_STDERR has been defined for) s
-5 195 M
-( stderr data.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(6.7 Window Dimension Change Message) s
-5 668 M
-( When the window \(terminal\) size changes on the client side, it MAY) s
-5 657 M
-( send a message to the other side to inform it of the new dimensions.) s
-5 635 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 624 M
-( uint32 recipient_channel) s
-5 613 M
-( string "window-change") s
-5 602 M
-( boolean FALSE) s
-5 591 M
-( uint32 terminal width, columns) s
-5 580 M
-( uint32 terminal height, rows) s
-5 569 M
-( uint32 terminal width, pixels) s
-5 558 M
-( uint32 terminal height, pixels) s
-5 536 M
-( No response SHOULD be sent to this message.) s
-5 514 M
-(6.8 Local Flow Control) s
-5 492 M
-( On many systems, it is possible to determine if a pseudo-terminal is) s
-5 481 M
-( using control-S/control-Q flow control. When flow control is) s
-5 470 M
-( allowed, it is often desirable to do the flow control at the client) s
-5 459 M
-( end to speed up responses to user requests. This is facilitated by) s
-5 448 M
-( the following notification. Initially, the server is responsible for) s
-5 437 M
-( flow control. \(Here, again, client means the side originating the) s
-5 426 M
-( session, and server means the other side.\)) s
-5 404 M
-( The message below is used by the server to inform the client when it) s
-5 393 M
-( can or cannot perform flow control \(control-S/control-Q processing\).) s
-5 382 M
-( If `client can do' is TRUE, the client is allowed to do flow control) s
-5 371 M
-( using control-S and control-Q. The client MAY ignore this message.) s
-5 349 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 338 M
-( uint32 recipient channel) s
-5 327 M
-( string "xon-xoff") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( boolean client can do) s
-5 283 M
-( No response is sent to this message.) s
-5 261 M
-(6.9 Signals) s
-5 239 M
-( A signal can be delivered to the remote process/service using the) s
-5 228 M
-( following message. Some systems may not implement signals, in which) s
-5 217 M
-( case they SHOULD ignore this message.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 184 M
-( uint32 recipient channel) s
-5 173 M
-( string "signal") s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( boolean FALSE) s
-5 679 M
-( string signal name without the "SIG" prefix.) s
-5 657 M
-( Signal names will be encoded as discussed in the "exit-signal") s
-5 646 M
-( SSH_MSG_CHANNEL_REQUEST.) s
-5 624 M
-(6.10 Returning Exit Status) s
-5 602 M
-( When the command running at the other end terminates, the following) s
-5 591 M
-( message can be sent to return the exit status of the command.) s
-5 580 M
-( Returning the status is RECOMMENDED. No acknowledgment is sent for) s
-5 569 M
-( this message. The channel needs to be closed with) s
-5 558 M
-( SSH_MSG_CHANNEL_CLOSE after this message.) s
-5 536 M
-( The client MAY ignore these messages.) s
-5 514 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 503 M
-( uint32 recipient_channel) s
-5 492 M
-( string "exit-status") s
-5 481 M
-( boolean FALSE) s
-5 470 M
-( uint32 exit_status) s
-5 448 M
-( The remote command may also terminate violently due to a signal.) s
-5 437 M
-( Such a condition can be indicated by the following message. A zero) s
-5 426 M
-( exit_status usually means that the command terminated successfully.) s
-5 404 M
-( byte SSH_MSG_CHANNEL_REQUEST) s
-5 393 M
-( uint32 recipient channel) s
-5 382 M
-( string "exit-signal") s
-5 371 M
-( boolean FALSE) s
-5 360 M
-( string signal name without the "SIG" prefix.) s
-5 349 M
-( boolean core dumped) s
-5 338 M
-( string error message \(ISO-10646 UTF-8\)) s
-5 327 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 305 M
-( The signal name is one of the following \(these are from [POSIX]\)) s
-5 283 M
-( ABRT) s
-5 272 M
-( ALRM) s
-5 261 M
-( FPE) s
-5 250 M
-( HUP) s
-5 239 M
-( ILL) s
-5 228 M
-( INT) s
-5 217 M
-( KILL) s
-5 206 M
-( PIPE) s
-5 195 M
-( QUIT) s
-5 184 M
-( SEGV) s
-5 173 M
-( TERM) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( USR1) s
-5 679 M
-( USR2) s
-5 657 M
-( Additional signal names MAY be sent in the format "sig-name@xyz",) s
-5 646 M
-( where `sig-name' and `xyz' may be anything a particular implementor) s
-5 635 M
-( wants \(except the `@' sign\). However, it is suggested that if a) s
-5 624 M
-( `configure' script is used, the non-standard signal names it finds be) s
-5 613 M
-( encoded as "[email protected]", where `SIG' is the signal name) s
-5 602 M
-( without the "SIG" prefix, and `xyz' be the host type, as determined) s
-5 591 M
-( by `config.guess'.) s
-5 569 M
-( The `error message' contains an additional explanation of the error) s
-5 558 M
-( message. The message may consist of multiple lines. The client) s
-5 547 M
-( software MAY display this message to the user. If this is done, the) s
-5 536 M
-( client software should take the precautions discussed in [SSH-ARCH].) s
-5 514 M
-(7. TCP/IP Port Forwarding) s
-5 492 M
-(7.1 Requesting Port Forwarding) s
-5 470 M
-( A party need not explicitly request forwardings from its own end to) s
-5 459 M
-( the other direction. However, if it wishes that connections to a) s
-5 448 M
-( port on the other side be forwarded to the local side, it must) s
-5 437 M
-( explicitly request this.) s
-5 404 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 393 M
-( string "tcpip-forward") s
-5 382 M
-( boolean want reply) s
-5 371 M
-( string address to bind \(e.g. "0.0.0.0"\)) s
-5 360 M
-( uint32 port number to bind) s
-5 338 M
-( `Address to bind' and `port number to bind' specify the IP address) s
-5 327 M
-( and port to which the socket to be listened is bound. The address) s
-5 316 M
-( should be "0.0.0.0" if connections are allowed from anywhere. \(Note) s
-5 305 M
-( that the client can still filter connections based on information) s
-5 294 M
-( passed in the open request.\)) s
-5 272 M
-( Implementations should only allow forwarding privileged ports if the) s
-5 261 M
-( user has been authenticated as a privileged user.) s
-5 239 M
-( Client implementations SHOULD reject these messages; they are) s
-5 228 M
-( normally only sent by the client.) s
-5 195 M
-( If a client passes 0 as port number to bind and has want reply TRUE) s
-5 184 M
-( then the server allocates the next available unprivileged port number) s
-5 173 M
-( and replies with the following message, otherwise there is no) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( response specific data.) s
-5 657 M
-( byte SSH_MSG_GLOBAL_REQUEST_SUCCESS) s
-5 646 M
-( uint32 port that was bound on the server) s
-5 624 M
-( A port forwarding can be cancelled with the following message. Note) s
-5 613 M
-( that channel open requests may be received until a reply to this) s
-5 602 M
-( message is received.) s
-5 580 M
-( byte SSH_MSG_GLOBAL_REQUEST) s
-5 569 M
-( string "cancel-tcpip-forward") s
-5 558 M
-( boolean want reply) s
-5 547 M
-( string address_to_bind \(e.g. "127.0.0.1"\)) s
-5 536 M
-( uint32 port number to bind) s
-5 514 M
-( Client implementations SHOULD reject these messages; they are) s
-5 503 M
-( normally only sent by the client.) s
-5 481 M
-(7.2 TCP/IP Forwarding Channels) s
-5 459 M
-( When a connection comes to a port for which remote forwarding has) s
-5 448 M
-( been requested, a channel is opened to forward the port to the other) s
-5 437 M
-( side.) s
-5 415 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 404 M
-( string "forwarded-tcpip") s
-5 393 M
-( uint32 sender channel) s
-5 382 M
-( uint32 initial window size) s
-5 371 M
-( uint32 maximum packet size) s
-5 360 M
-( string address that was connected) s
-5 349 M
-( uint32 port that was connected) s
-5 338 M
-( string originator IP address) s
-5 327 M
-( uint32 originator port) s
-5 305 M
-( Implementations MUST reject these messages unless they have) s
-5 294 M
-( previously requested a remote TCP/IP port forwarding with the given) s
-5 283 M
-( port number.) s
-5 261 M
-( When a connection comes to a locally forwarded TCP/IP port, the) s
-5 250 M
-( following packet is sent to the other side. Note that these messages) s
-5 239 M
-( MAY be sent also for ports for which no forwarding has been) s
-5 228 M
-( explicitly requested. The receiving side must decide whether to) s
-5 217 M
-( allow the forwarding.) s
-5 195 M
-( byte SSH_MSG_CHANNEL_OPEN) s
-5 184 M
-( string "direct-tcpip") s
-5 173 M
-( uint32 sender channel) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( uint32 initial window size) s
-5 679 M
-( uint32 maximum packet size) s
-5 668 M
-( string host to connect) s
-5 657 M
-( uint32 port to connect) s
-5 646 M
-( string originator IP address) s
-5 635 M
-( uint32 originator port) s
-5 613 M
-( `Host to connect' and `port to connect' specify the TCP/IP host and) s
-5 602 M
-( port where the recipient should connect the channel. `Host to) s
-5 591 M
-( connect' may be either a domain name or a numeric IP address.) s
-5 569 M
-( `Originator IP address' is the numeric IP address of the machine) s
-5 558 M
-( where the connection request comes from, and `originator port' is the) s
-5 547 M
-( port on the originator host from where the connection came from.) s
-5 525 M
-( Forwarded TCP/IP channels are independent of any sessions, and) s
-5 514 M
-( closing a session channel does not in any way imply that forwarded) s
-5 503 M
-( connections should be closed.) s
-5 481 M
-( Client implementations SHOULD reject direct TCP/IP open requests for) s
-5 470 M
-( security reasons.) s
-5 448 M
-(8. Encoding of Terminal Modes) s
-5 426 M
-( Terminal modes \(as passed in a pty request\) are encoded into a byte) s
-5 415 M
-( stream. It is intended that the coding be portable across different) s
-5 404 M
-( environments.) s
-5 382 M
-( The tty mode description is a stream of bytes. The stream consists) s
-5 371 M
-( of opcode-argument pairs. It is terminated by opcode TTY_OP_END \(0\).) s
-5 360 M
-( Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255) s
-5 349 M
-( are not yet defined, and cause parsing to stop \(they should only be) s
-5 338 M
-( used after any other data\).) s
-5 316 M
-( The client SHOULD put in the stream any modes it knows about, and the) s
-5 305 M
-( server MAY ignore any modes it does not know about. This allows some) s
-5 294 M
-( degree of machine-independence, at least between systems that use a) s
-5 283 M
-( POSIX-like tty interface. The protocol can support other systems as) s
-5 272 M
-( well, but the client may need to fill reasonable values for a number) s
-5 261 M
-( of parameters so the server pty gets set to a reasonable mode \(the) s
-5 250 M
-( server leaves all unspecified mode bits in their default values, and) s
-5 239 M
-( only some combinations make sense\).) s
-5 217 M
-( The following opcodes have been defined. The naming of opcodes) s
-5 206 M
-( mostly follows the POSIX terminal mode flags.) s
-5 184 M
-( 0 TTY_OP_END Indicates end of options.) s
-5 173 M
-( 1 VINTR Interrupt character; 255 if none. Similarly for the) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( other characters. Not all of these characters are) s
-5 679 M
-( supported on all systems.) s
-5 668 M
-( 2 VQUIT The quit character \(sends SIGQUIT signal on POSIX) s
-5 657 M
-( systems\).) s
-5 646 M
-( 3 VERASE Erase the character to left of the cursor.) s
-5 635 M
-( 4 VKILL Kill the current input line.) s
-5 624 M
-( 5 VEOF End-of-file character \(sends EOF from the terminal\).) s
-5 613 M
-( 6 VEOL End-of-line character in addition to carriage return) s
-5 602 M
-( and/or linefeed.) s
-5 591 M
-( 7 VEOL2 Additional end-of-line character.) s
-5 580 M
-( 8 VSTART Continues paused output \(normally control-Q\).) s
-5 569 M
-( 9 VSTOP Pauses output \(normally control-S\).) s
-5 558 M
-( 10 VSUSP Suspends the current program.) s
-5 547 M
-( 11 VDSUSP Another suspend character.) s
-5 536 M
-( 12 VREPRINT Reprints the current input line.) s
-5 525 M
-( 13 VWERASE Erases a word left of cursor.) s
-5 514 M
-( 14 VLNEXT Enter the next character typed literally, even if it) s
-5 503 M
-( is a special character) s
-5 492 M
-( 15 VFLUSH Character to flush output.) s
-5 481 M
-( 16 VSWTCH Switch to a different shell layer.) s
-5 470 M
-( 17 VSTATUS Prints system status line \(load, command, pid etc\).) s
-5 459 M
-( 18 VDISCARD Toggles the flushing of terminal output.) s
-5 448 M
-( 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if) s
-5 437 M
-( this flag is FALSE set, and 1 if it is TRUE.) s
-5 426 M
-( 31 PARMRK Mark parity and framing errors.) s
-5 415 M
-( 32 INPCK Enable checking of parity errors.) s
-5 404 M
-( 33 ISTRIP Strip 8th bit off characters.) s
-5 393 M
-( 34 INLCR Map NL into CR on input.) s
-5 382 M
-( 35 IGNCR Ignore CR on input.) s
-5 371 M
-( 36 ICRNL Map CR to NL on input.) s
-5 360 M
-( 37 IUCLC Translate uppercase characters to lowercase.) s
-5 349 M
-( 38 IXON Enable output flow control.) s
-5 338 M
-( 39 IXANY Any char will restart after stop.) s
-5 327 M
-( 40 IXOFF Enable input flow control.) s
-5 316 M
-( 41 IMAXBEL Ring bell on input queue full.) s
-5 305 M
-( 50 ISIG Enable signals INTR, QUIT, [D]SUSP.) s
-5 294 M
-( 51 ICANON Canonicalize input lines.) s
-5 283 M
-( 52 XCASE Enable input and output of uppercase characters by) s
-5 272 M
-( preceding their lowercase equivalents with `\\'.) s
-5 261 M
-( 53 ECHO Enable echoing.) s
-5 250 M
-( 54 ECHOE Visually erase chars.) s
-5 239 M
-( 55 ECHOK Kill character discards current line.) s
-5 228 M
-( 56 ECHONL Echo NL even if ECHO is off.) s
-5 217 M
-( 57 NOFLSH Don't flush after interrupt.) s
-5 206 M
-( 58 TOSTOP Stop background jobs from output.) s
-5 195 M
-( 59 IEXTEN Enable extensions.) s
-5 184 M
-( 60 ECHOCTL Echo control characters as ^\(Char\).) s
-5 173 M
-( 61 ECHOKE Visual erase for line kill.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 62 PENDIN Retype pending input.) s
-5 679 M
-( 70 OPOST Enable output processing.) s
-5 668 M
-( 71 OLCUC Convert lowercase to uppercase.) s
-5 657 M
-( 72 ONLCR Map NL to CR-NL.) s
-5 646 M
-( 73 OCRNL Translate carriage return to newline \(output\).) s
-5 635 M
-( 74 ONOCR Translate newline to carriage return-newline) s
-5 624 M
-( \(output\).) s
-5 613 M
-( 75 ONLRET Newline performs a carriage return \(output\).) s
-5 602 M
-( 90 CS7 7 bit mode.) s
-5 591 M
-( 91 CS8 8 bit mode.) s
-5 580 M
-( 92 PARENB Parity enable.) s
-5 569 M
-( 93 PARODD Odd parity, else even.) s
-5 547 M
-( 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.) s
-5 536 M
-( 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.) s
-5 503 M
-(9. Summary of Message Numbers) s
-5 481 M
-( #define SSH_MSG_GLOBAL_REQUEST 80) s
-5 470 M
-( #define SSH_MSG_REQUEST_SUCCESS 81) s
-5 459 M
-( #define SSH_MSG_REQUEST_FAILURE 82) s
-5 448 M
-( #define SSH_MSG_CHANNEL_OPEN 90) s
-5 437 M
-( #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91) s
-5 426 M
-( #define SSH_MSG_CHANNEL_OPEN_FAILURE 92) s
-5 415 M
-( #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93) s
-5 404 M
-( #define SSH_MSG_CHANNEL_DATA 94) s
-5 393 M
-( #define SSH_MSG_CHANNEL_EXTENDED_DATA 95) s
-5 382 M
-( #define SSH_MSG_CHANNEL_EOF 96) s
-5 371 M
-( #define SSH_MSG_CHANNEL_CLOSE 97) s
-5 360 M
-( #define SSH_MSG_CHANNEL_REQUEST 98) s
-5 349 M
-( #define SSH_MSG_CHANNEL_SUCCESS 99) s
-5 338 M
-( #define SSH_MSG_CHANNEL_FAILURE 100) s
-5 305 M
-(10. Security Considerations) s
-5 283 M
-( This protocol is assumed to run on top of a secure, authenticated) s
-5 272 M
-( transport. User authentication and protection against network-level) s
-5 261 M
-( attacks are assumed to be provided by the underlying protocols.) s
-5 239 M
-( It is RECOMMENDED that implementations disable all the potentially) s
-5 228 M
-( dangerous features \(e.g. agent forwarding, X11 forwarding, and TCP/IP) s
-5 217 M
-( forwarding\) if the host key has changed.) s
-5 195 M
-( Full security considerations for this protocol are provided in) s
-5 184 M
-( Section 8 of [SSH-ARCH]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(11. iana cONSiderations) s
-5 668 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 657 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 646 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 624 M
-(12. Intellectual Property) s
-5 602 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 591 M
-( intellectual property or other rights that might be claimed to) s
-5 580 M
-( pertain to the implementation or use of the technology described in) s
-5 569 M
-( this document or the extent to which any license under such rights) s
-5 558 M
-( might or might not be available; neither does it represent that it) s
-5 547 M
-( has made any effort to identify any such rights. Information on the) s
-5 536 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 525 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 514 M
-( claims of rights made available for publication and any assurances of) s
-5 503 M
-( licenses to be made available, or the result of an attempt made to) s
-5 492 M
-( obtain a general license or permission for the use of such) s
-5 481 M
-( proprietary rights by implementers or users of this specification can) s
-5 470 M
-( be obtained from the IETF Secretariat.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 393 M
-(Normative References) s
-5 371 M
-( [SSH-ARCH]) s
-5 360 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 349 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 327 M
-( [SSH-TRANS]) s
-5 316 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 305 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 283 M
-( [SSH-USERAUTH]) s
-5 272 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 261 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 239 M
-( [SSH-CONNECT]) s
-5 228 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 217 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 195 M
-( [SSH-NUMBERS]) s
-5 184 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 173 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( 2003.) s
-5 668 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 657 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 635 M
-(Informative References) s
-5 613 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 602 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 580 M
-( [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing) s
-5 569 M
-( Architecture", RFC 1884, December 1995.) s
-5 547 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 536 M
-( 10646", RFC 2279, January 1998.) s
-5 514 M
-( [SCHEIFLER]) s
-5 503 M
-( Scheifler, R., "X Window System : The Complete Reference) s
-5 492 M
-( to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital) s
-5 481 M
-( Press ISBN 1555580882, Feburary 1992.) s
-5 459 M
-( [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable) s
-5 448 M
-( Operating System Interface \(POSIX\)-Part 1: System) s
-5 437 M
-( Application Program Interface \(API\) C Language", ANSI/IEE) s
-5 426 M
-( Std 1003.1, July 1996.) s
-5 393 M
-(Authors' Addresses) s
-5 371 M
-( Tatu Ylonen) s
-5 360 M
-( SSH Communications Security Corp) s
-5 349 M
-( Fredrikinkatu 42) s
-5 338 M
-( HELSINKI FIN-00100) s
-5 327 M
-( Finland) s
-5 305 M
-( EMail: [email protected]) s
-5 272 M
-( Darren J. Moffat \(editor\)) s
-5 261 M
-( Sun Microsystems, Inc) s
-5 250 M
-( 17 Network Circle) s
-5 239 M
-( Menlo Park CA 94025) s
-5 228 M
-( USA) s
-5 206 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Connection Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 22
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
deleted file mode 100644
index 1cb8ad6409..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-connect-18.txt
+++ /dev/null
@@ -1,1232 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Connection Protocol
- draft-ietf-secsh-connect-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH Connection Protocol. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. All of these
- channels are multiplexed into a single encrypted tunnel.
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Global Requests . . . . . . . . . . . . . . . . . . . . . . 3
- 5. Channel Mechanism . . . . . . . . . . . . . . . . . . . . . 4
- 5.1 Opening a Channel . . . . . . . . . . . . . . . . . . . . . 4
- 5.2 Data Transfer . . . . . . . . . . . . . . . . . . . . . . . 5
- 5.3 Closing a Channel . . . . . . . . . . . . . . . . . . . . . 6
- 5.4 Channel-Specific Requests . . . . . . . . . . . . . . . . . 7
- 6. Interactive Sessions . . . . . . . . . . . . . . . . . . . . 8
- 6.1 Opening a Session . . . . . . . . . . . . . . . . . . . . . 8
- 6.2 Requesting a Pseudo-Terminal . . . . . . . . . . . . . . . . 8
- 6.3 X11 Forwarding . . . . . . . . . . . . . . . . . . . . . . . 9
- 6.3.1 Requesting X11 Forwarding . . . . . . . . . . . . . . . . . 9
- 6.3.2 X11 Channels . . . . . . . . . . . . . . . . . . . . . . . . 10
- 6.4 Environment Variable Passing . . . . . . . . . . . . . . . . 10
- 6.5 Starting a Shell or a Command . . . . . . . . . . . . . . . 10
- 6.6 Session Data Transfer . . . . . . . . . . . . . . . . . . . 11
- 6.7 Window Dimension Change Message . . . . . . . . . . . . . . 12
- 6.8 Local Flow Control . . . . . . . . . . . . . . . . . . . . . 12
- 6.9 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 6.10 Returning Exit Status . . . . . . . . . . . . . . . . . . . 13
- 7. TCP/IP Port Forwarding . . . . . . . . . . . . . . . . . . . 14
- 7.1 Requesting Port Forwarding . . . . . . . . . . . . . . . . . 14
- 7.2 TCP/IP Forwarding Channels . . . . . . . . . . . . . . . . . 15
- 8. Encoding of Terminal Modes . . . . . . . . . . . . . . . . . 16
- 9. Summary of Message Numbers . . . . . . . . . . . . . . . . . 18
- 10. Security Considerations . . . . . . . . . . . . . . . . . . 18
- 11. iana cONSiderations . . . . . . . . . . . . . . . . . . . . 19
- 12. Intellectual Property . . . . . . . . . . . . . . . . . . . 19
- Normative References . . . . . . . . . . . . . . . . . . . . 19
- Informative References . . . . . . . . . . . . . . . . . . . 20
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 20
- Intellectual Property and Copyright Statements . . . . . . . 21
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH Connection Protocol has been designed to run on top of the
- SSH transport layer and user authentication protocols. It provides
- interactive login sessions, remote execution of commands, forwarded
- TCP/IP connections, and forwarded X11 connections. The service name
- for this protocol is "ssh-connection".
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Global Requests
-
- There are several kinds of requests that affect the state of the
- remote end "globally", independent of any channels. An example is a
- request to start TCP/IP forwarding for a specific port. All such
- requests use the following format.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string request name (restricted to US-ASCII)
- boolean want reply
- ... request-specific data follows
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- Request names follow the DNS extensibility naming convention outlined
- in [SSH-ARCH].
-
- The recipient will respond to this message with
- SSH_MSG_REQUEST_SUCCESS or SSH_MSG_REQUEST_FAILURE if `want reply' is
- TRUE.
-
- byte SSH_MSG_REQUEST_SUCCESS
- ..... response specific data
-
- Usually the response specific data is non-existent.
-
- If the recipient does not recognize or support the request, it simply
- responds with SSH_MSG_REQUEST_FAILURE.
-
- byte SSH_MSG_REQUEST_FAILURE
-
-
-5. Channel Mechanism
-
- All terminal sessions, forwarded connections, etc. are channels.
- Either side may open a channel. Multiple channels are multiplexed
- into a single connection.
-
- Channels are identified by numbers at each end. The number referring
- to a channel may be different on each side. Requests to open a
- channel contain the sender's channel number. Any other
- channel-related messages contain the recipient's channel number for
- the channel.
-
- Channels are flow-controlled. No data may be sent to a channel until
- a message is received to indicate that window space is available.
-
-5.1 Opening a Channel
-
- When either side wishes to open a new channel, it allocates a local
- number for the channel. It then sends the following message to the
- other side, and includes the local channel number and initial window
- size in the message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string channel type (restricted to US-ASCII)
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- The channel type is a name as described in the SSH architecture
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- document, with similar extension mechanisms. `sender channel' is a
- local identifier for the channel used by the sender of this message.
- `initial window size' specifies how many bytes of channel data can be
- sent to the sender of this message without adjusting the window.
- `Maximum packet size' specifies the maximum size of an individual
- data packet that can be sent to the sender (for example, one might
- want to use smaller packets for interactive connections to get better
- interactive response on slow links).
-
- The remote side then decides whether it can open the channel, and
- responds with either
-
- byte SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- uint32 recipient channel
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- ... channel type specific data follows
-
- where `recipient channel' is the channel number given in the original
- open request, and `sender channel' is the channel number allocated by
- the other side, or
-
- byte SSH_MSG_CHANNEL_OPEN_FAILURE
- uint32 recipient channel
- uint32 reason code
- string additional textual information (ISO-10646 UTF-8 [RFC2279])
- string language tag (as defined in [RFC3066])
-
- If the recipient of the SSH_MSG_CHANNEL_OPEN message does not support
- the specified channel type, it simply responds with
- SSH_MSG_CHANNEL_OPEN_FAILURE. The client MAY show the additional
- information to the user. If this is done, the client software should
- take the precautions discussed in [SSH-ARCH].
-
- The following reason codes are defined:
-
- #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
- #define SSH_OPEN_CONNECT_FAILED 2
- #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
- #define SSH_OPEN_RESOURCE_SHORTAGE 4
-
-
-5.2 Data Transfer
-
- The window size specifies how many bytes the other party can send
- before it must wait for the window to be adjusted. Both parties use
- the following message to adjust the window.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- byte SSH_MSG_CHANNEL_WINDOW_ADJUST
- uint32 recipient channel
- uint32 bytes to add
-
- After receiving this message, the recipient MAY send the given number
- of bytes more than it was previously allowed to send; the window size
- is incremented.
-
- Data transfer is done with messages of the following type.
-
- byte SSH_MSG_CHANNEL_DATA
- uint32 recipient channel
- string data
-
- The maximum amount of data allowed is the current window size. The
- window size is decremented by the amount of data sent. Both parties
- MAY ignore all extra data sent after the allowed window is empty.
-
- Additionally, some channels can transfer several types of data. An
- example of this is stderr data from interactive sessions. Such data
- can be passed with SSH_MSG_CHANNEL_EXTENDED_DATA messages, where a
- separate integer specifies the type of the data. The available types
- and their interpretation depend on the type of the channel.
-
- byte SSH_MSG_CHANNEL_EXTENDED_DATA
- uint32 recipient_channel
- uint32 data_type_code
- string data
-
- Data sent with these messages consumes the same window as ordinary
- data.
-
- Currently, only the following type is defined.
-
- #define SSH_EXTENDED_DATA_STDERR 1
-
-
-5.3 Closing a Channel
-
- When a party will no longer send more data to a channel, it SHOULD
- send SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_EOF
- uint32 recipient_channel
-
- No explicit response is sent to this message; however, the
- application may send EOF to whatever is at the other end of the
- channel. Note that the channel remains open after this message, and
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- more data may still be sent in the other direction. This message
- does not consume window space and can be sent even if no window space
- is available.
-
- When either party wishes to terminate the channel, it sends
- SSH_MSG_CHANNEL_CLOSE. Upon receiving this message, a party MUST
- send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
- message for the channel. The channel is considered closed for a
- party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
- the party may then reuse the channel number. A party MAY send
- SSH_MSG_CHANNEL_CLOSE without having sent or received
- SSH_MSG_CHANNEL_EOF.
-
- byte SSH_MSG_CHANNEL_CLOSE
- uint32 recipient_channel
-
- This message does not consume window space and can be sent even if no
- window space is available.
-
- It is recommended that any data sent before this message is delivered
- to the actual destination, if possible.
-
-5.4 Channel-Specific Requests
-
- Many channel types have extensions that are specific to that
- particular channel type. An example is requesting a pty (pseudo
- terminal) for an interactive session.
-
- All channel-specific requests use the following format.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string request type (restricted to US-ASCII)
- boolean want reply
- ... type-specific data
-
- If want reply is FALSE, no response will be sent to the request.
- Otherwise, the recipient responds with either SSH_MSG_CHANNEL_SUCCESS
- or SSH_MSG_CHANNEL_FAILURE, or request-specific continuation
- messages. If the request is not recognized or is not supported for
- the channel, SSH_MSG_CHANNEL_FAILURE is returned.
-
- This message does not consume window space and can be sent even if no
- window space is available. Request types are local to each channel
- type.
-
- The client is allowed to send further messages without waiting for
- the response to the request.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- request type names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH]
-
- byte SSH_MSG_CHANNEL_SUCCESS
- uint32 recipient_channel
-
-
- byte SSH_MSG_CHANNEL_FAILURE
- uint32 recipient_channel
-
- These messages do not consume window space and can be sent even if no
- window space is available.
-
-6. Interactive Sessions
-
- A session is a remote execution of a program. The program may be a
- shell, an application, a system command, or some built-in subsystem.
- It may or may not have a tty, and may or may not involve X11
- forwarding. Multiple sessions can be active simultaneously.
-
-6.1 Opening a Session
-
- A session is started by sending the following message.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "session"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
-
- Client implementations SHOULD reject any session channel open
- requests to make it more difficult for a corrupt server to attack the
- client.
-
-6.2 Requesting a Pseudo-Terminal
-
- A pseudo-terminal can be allocated for the session by sending the
- following message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "pty-req"
- boolean want_reply
- string TERM environment variable value (e.g., vt100)
- uint32 terminal width, characters (e.g., 80)
- uint32 terminal height, rows (e.g., 24)
- uint32 terminal width, pixels (e.g., 640)
- uint32 terminal height, pixels (e.g., 480)
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- string encoded terminal modes
-
- The encoding of terminal modes is described in Section Encoding of
- Terminal Modes (Section 8). Zero dimension parameters MUST be
- ignored. The character/row dimensions override the pixel dimensions
- (when nonzero). Pixel dimensions refer to the drawable area of the
- window.
-
- The dimension parameters are only informational.
-
- The client SHOULD ignore pty requests.
-
-6.3 X11 Forwarding
-
-6.3.1 Requesting X11 Forwarding
-
- X11 forwarding may be requested for a session by sending
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "x11-req"
- boolean want reply
- boolean single connection
- string x11 authentication protocol
- string x11 authentication cookie
- uint32 x11 screen number
-
- It is recommended that the authentication cookie that is sent be a
- fake, random cookie, and that the cookie is checked and replaced by
- the real cookie when a connection request is received.
-
- X11 connection forwarding should stop when the session channel is
- closed; however, already opened forwardings should not be
- automatically closed when the session channel is closed.
-
- If `single connection' is TRUE, only a single connection should be
- forwarded. No more connections will be forwarded after the first, or
- after the session channel has been closed.
-
- The "x11 authentication protocol" is the name of the X11
- authentication method used, e.g. "MIT-MAGIC-COOKIE-1".
-
- The x11 authentication cookie MUST be hexadecimal encoded.
-
- X Protocol is documented in [SCHEIFLER].
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.3.2 X11 Channels
-
- X11 channels are opened with a channel open request. The resulting
- channels are independent of the session, and closing the session
- channel does not close the forwarded X11 channels.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "x11"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string originator address (e.g. "192.168.7.38")
- uint32 originator port
-
- The recipient should respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION
- or SSH_MSG_CHANNEL_OPEN_FAILURE.
-
- Implementations MUST reject any X11 channel open requests if they
- have not requested X11 forwarding.
-
-6.4 Environment Variable Passing
-
- Environment variables may be passed to the shell/command to be
- started later. Uncontrolled setting of environment variables in a
- privileged process can be a security hazard. It is recommended that
- implementations either maintain a list of allowable variable names or
- only set environment variables after the server process has dropped
- sufficient privileges.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "env"
- boolean want reply
- string variable name
- string variable value
-
-
-6.5 Starting a Shell or a Command
-
- Once the session has been set up, a program is started at the remote
- end. The program can be a shell, an application program or a
- subsystem with a host-independent name. Only one of these requests
- can succeed per channel.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "shell"
- boolean want reply
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This message will request the user's default shell (typically defined
- in /etc/passwd in UNIX systems) to be started at the other end.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exec"
- boolean want reply
- string command
-
- This message will request the server to start the execution of the
- given command. The command string may contain a path. Normal
- precautions MUST be taken to prevent the execution of unauthorized
- commands.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "subsystem"
- boolean want reply
- string subsystem name
-
- This last form executes a predefined subsystem. It is expected that
- these will include a general file transfer mechanism, and possibly
- other features. Implementations may also allow configuring more such
- mechanisms. As the user's shell is usually used to execute the
- subsystem, it is advisable for the subsystem protocol to have a
- "magic cookie" at the beginning of the protocol transaction to
- distinguish it from arbitrary output generated by shell
- initialization scripts etc. This spurious output from the shell may
- be filtered out either at the server or at the client.
-
- The server SHOULD not halt the execution of the protocol stack when
- starting a shell or a program. All input and output from these SHOULD
- be redirected to the channel or to the encrypted tunnel.
-
- It is RECOMMENDED to request and check the reply for these messages.
- The client SHOULD ignore these messages.
-
- Subsystem names follow the DNS extensibility naming convention
- outlined in [SSH-ARCH].
-
-6.6 Session Data Transfer
-
- Data transfer for a session is done using SSH_MSG_CHANNEL_DATA and
- SSH_MSG_CHANNEL_EXTENDED_DATA packets and the window mechanism. The
- extended data type SSH_EXTENDED_DATA_STDERR has been defined for
- stderr data.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-6.7 Window Dimension Change Message
-
- When the window (terminal) size changes on the client side, it MAY
- send a message to the other side to inform it of the new dimensions.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "window-change"
- boolean FALSE
- uint32 terminal width, columns
- uint32 terminal height, rows
- uint32 terminal width, pixels
- uint32 terminal height, pixels
-
- No response SHOULD be sent to this message.
-
-6.8 Local Flow Control
-
- On many systems, it is possible to determine if a pseudo-terminal is
- using control-S/control-Q flow control. When flow control is
- allowed, it is often desirable to do the flow control at the client
- end to speed up responses to user requests. This is facilitated by
- the following notification. Initially, the server is responsible for
- flow control. (Here, again, client means the side originating the
- session, and server means the other side.)
-
- The message below is used by the server to inform the client when it
- can or cannot perform flow control (control-S/control-Q processing).
- If `client can do' is TRUE, the client is allowed to do flow control
- using control-S and control-Q. The client MAY ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "xon-xoff"
- boolean FALSE
- boolean client can do
-
- No response is sent to this message.
-
-6.9 Signals
-
- A signal can be delivered to the remote process/service using the
- following message. Some systems may not implement signals, in which
- case they SHOULD ignore this message.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "signal"
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- boolean FALSE
- string signal name without the "SIG" prefix.
-
- Signal names will be encoded as discussed in the "exit-signal"
- SSH_MSG_CHANNEL_REQUEST.
-
-6.10 Returning Exit Status
-
- When the command running at the other end terminates, the following
- message can be sent to return the exit status of the command.
- Returning the status is RECOMMENDED. No acknowledgment is sent for
- this message. The channel needs to be closed with
- SSH_MSG_CHANNEL_CLOSE after this message.
-
- The client MAY ignore these messages.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient_channel
- string "exit-status"
- boolean FALSE
- uint32 exit_status
-
- The remote command may also terminate violently due to a signal.
- Such a condition can be indicated by the following message. A zero
- exit_status usually means that the command terminated successfully.
-
- byte SSH_MSG_CHANNEL_REQUEST
- uint32 recipient channel
- string "exit-signal"
- boolean FALSE
- string signal name without the "SIG" prefix.
- boolean core dumped
- string error message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The signal name is one of the following (these are from [POSIX])
-
- ABRT
- ALRM
- FPE
- HUP
- ILL
- INT
- KILL
- PIPE
- QUIT
- SEGV
- TERM
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- USR1
- USR2
-
- Additional signal names MAY be sent in the format "sig-name@xyz",
- where `sig-name' and `xyz' may be anything a particular implementor
- wants (except the `@' sign). However, it is suggested that if a
- `configure' script is used, the non-standard signal names it finds be
- encoded as "[email protected]", where `SIG' is the signal name
- without the "SIG" prefix, and `xyz' be the host type, as determined
- by `config.guess'.
-
- The `error message' contains an additional explanation of the error
- message. The message may consist of multiple lines. The client
- software MAY display this message to the user. If this is done, the
- client software should take the precautions discussed in [SSH-ARCH].
-
-7. TCP/IP Port Forwarding
-
-7.1 Requesting Port Forwarding
-
- A party need not explicitly request forwardings from its own end to
- the other direction. However, if it wishes that connections to a
- port on the other side be forwarded to the local side, it must
- explicitly request this.
-
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "tcpip-forward"
- boolean want reply
- string address to bind (e.g. "0.0.0.0")
- uint32 port number to bind
-
- `Address to bind' and `port number to bind' specify the IP address
- and port to which the socket to be listened is bound. The address
- should be "0.0.0.0" if connections are allowed from anywhere. (Note
- that the client can still filter connections based on information
- passed in the open request.)
-
- Implementations should only allow forwarding privileged ports if the
- user has been authenticated as a privileged user.
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-
- If a client passes 0 as port number to bind and has want reply TRUE
- then the server allocates the next available unprivileged port number
- and replies with the following message, otherwise there is no
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- response specific data.
-
-
- byte SSH_MSG_GLOBAL_REQUEST_SUCCESS
- uint32 port that was bound on the server
-
- A port forwarding can be cancelled with the following message. Note
- that channel open requests may be received until a reply to this
- message is received.
-
- byte SSH_MSG_GLOBAL_REQUEST
- string "cancel-tcpip-forward"
- boolean want reply
- string address_to_bind (e.g. "127.0.0.1")
- uint32 port number to bind
-
- Client implementations SHOULD reject these messages; they are
- normally only sent by the client.
-
-7.2 TCP/IP Forwarding Channels
-
- When a connection comes to a port for which remote forwarding has
- been requested, a channel is opened to forward the port to the other
- side.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "forwarded-tcpip"
- uint32 sender channel
- uint32 initial window size
- uint32 maximum packet size
- string address that was connected
- uint32 port that was connected
- string originator IP address
- uint32 originator port
-
- Implementations MUST reject these messages unless they have
- previously requested a remote TCP/IP port forwarding with the given
- port number.
-
- When a connection comes to a locally forwarded TCP/IP port, the
- following packet is sent to the other side. Note that these messages
- MAY be sent also for ports for which no forwarding has been
- explicitly requested. The receiving side must decide whether to
- allow the forwarding.
-
- byte SSH_MSG_CHANNEL_OPEN
- string "direct-tcpip"
- uint32 sender channel
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- uint32 initial window size
- uint32 maximum packet size
- string host to connect
- uint32 port to connect
- string originator IP address
- uint32 originator port
-
- `Host to connect' and `port to connect' specify the TCP/IP host and
- port where the recipient should connect the channel. `Host to
- connect' may be either a domain name or a numeric IP address.
-
- `Originator IP address' is the numeric IP address of the machine
- where the connection request comes from, and `originator port' is the
- port on the originator host from where the connection came from.
-
- Forwarded TCP/IP channels are independent of any sessions, and
- closing a session channel does not in any way imply that forwarded
- connections should be closed.
-
- Client implementations SHOULD reject direct TCP/IP open requests for
- security reasons.
-
-8. Encoding of Terminal Modes
-
- Terminal modes (as passed in a pty request) are encoded into a byte
- stream. It is intended that the coding be portable across different
- environments.
-
- The tty mode description is a stream of bytes. The stream consists
- of opcode-argument pairs. It is terminated by opcode TTY_OP_END (0).
- Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255
- are not yet defined, and cause parsing to stop (they should only be
- used after any other data).
-
- The client SHOULD put in the stream any modes it knows about, and the
- server MAY ignore any modes it does not know about. This allows some
- degree of machine-independence, at least between systems that use a
- POSIX-like tty interface. The protocol can support other systems as
- well, but the client may need to fill reasonable values for a number
- of parameters so the server pty gets set to a reasonable mode (the
- server leaves all unspecified mode bits in their default values, and
- only some combinations make sense).
-
- The following opcodes have been defined. The naming of opcodes
- mostly follows the POSIX terminal mode flags.
-
- 0 TTY_OP_END Indicates end of options.
- 1 VINTR Interrupt character; 255 if none. Similarly for the
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- other characters. Not all of these characters are
- supported on all systems.
- 2 VQUIT The quit character (sends SIGQUIT signal on POSIX
- systems).
- 3 VERASE Erase the character to left of the cursor.
- 4 VKILL Kill the current input line.
- 5 VEOF End-of-file character (sends EOF from the terminal).
- 6 VEOL End-of-line character in addition to carriage return
- and/or linefeed.
- 7 VEOL2 Additional end-of-line character.
- 8 VSTART Continues paused output (normally control-Q).
- 9 VSTOP Pauses output (normally control-S).
- 10 VSUSP Suspends the current program.
- 11 VDSUSP Another suspend character.
- 12 VREPRINT Reprints the current input line.
- 13 VWERASE Erases a word left of cursor.
- 14 VLNEXT Enter the next character typed literally, even if it
- is a special character
- 15 VFLUSH Character to flush output.
- 16 VSWTCH Switch to a different shell layer.
- 17 VSTATUS Prints system status line (load, command, pid etc).
- 18 VDISCARD Toggles the flushing of terminal output.
- 30 IGNPAR The ignore parity flag. The parameter SHOULD be 0 if
- this flag is FALSE set, and 1 if it is TRUE.
- 31 PARMRK Mark parity and framing errors.
- 32 INPCK Enable checking of parity errors.
- 33 ISTRIP Strip 8th bit off characters.
- 34 INLCR Map NL into CR on input.
- 35 IGNCR Ignore CR on input.
- 36 ICRNL Map CR to NL on input.
- 37 IUCLC Translate uppercase characters to lowercase.
- 38 IXON Enable output flow control.
- 39 IXANY Any char will restart after stop.
- 40 IXOFF Enable input flow control.
- 41 IMAXBEL Ring bell on input queue full.
- 50 ISIG Enable signals INTR, QUIT, [D]SUSP.
- 51 ICANON Canonicalize input lines.
- 52 XCASE Enable input and output of uppercase characters by
- preceding their lowercase equivalents with `\'.
- 53 ECHO Enable echoing.
- 54 ECHOE Visually erase chars.
- 55 ECHOK Kill character discards current line.
- 56 ECHONL Echo NL even if ECHO is off.
- 57 NOFLSH Don't flush after interrupt.
- 58 TOSTOP Stop background jobs from output.
- 59 IEXTEN Enable extensions.
- 60 ECHOCTL Echo control characters as ^(Char).
- 61 ECHOKE Visual erase for line kill.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 62 PENDIN Retype pending input.
- 70 OPOST Enable output processing.
- 71 OLCUC Convert lowercase to uppercase.
- 72 ONLCR Map NL to CR-NL.
- 73 OCRNL Translate carriage return to newline (output).
- 74 ONOCR Translate newline to carriage return-newline
- (output).
- 75 ONLRET Newline performs a carriage return (output).
- 90 CS7 7 bit mode.
- 91 CS8 8 bit mode.
- 92 PARENB Parity enable.
- 93 PARODD Odd parity, else even.
-
- 128 TTY_OP_ISPEED Specifies the input baud rate in bits per second.
- 129 TTY_OP_OSPEED Specifies the output baud rate in bits per second.
-
-
-9. Summary of Message Numbers
-
- #define SSH_MSG_GLOBAL_REQUEST 80
- #define SSH_MSG_REQUEST_SUCCESS 81
- #define SSH_MSG_REQUEST_FAILURE 82
- #define SSH_MSG_CHANNEL_OPEN 90
- #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
- #define SSH_MSG_CHANNEL_OPEN_FAILURE 92
- #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
- #define SSH_MSG_CHANNEL_DATA 94
- #define SSH_MSG_CHANNEL_EXTENDED_DATA 95
- #define SSH_MSG_CHANNEL_EOF 96
- #define SSH_MSG_CHANNEL_CLOSE 97
- #define SSH_MSG_CHANNEL_REQUEST 98
- #define SSH_MSG_CHANNEL_SUCCESS 99
- #define SSH_MSG_CHANNEL_FAILURE 100
-
-
-10. Security Considerations
-
- This protocol is assumed to run on top of a secure, authenticated
- transport. User authentication and protection against network-level
- attacks are assumed to be provided by the underlying protocols.
-
- It is RECOMMENDED that implementations disable all the potentially
- dangerous features (e.g. agent forwarding, X11 forwarding, and TCP/IP
- forwarding) if the host key has changed.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-11. iana cONSiderations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-12. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-Normative References
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative References
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1884] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 1884, December 1995.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [SCHEIFLER]
- Scheifler, R., "X Window System : The Complete Reference
- to Xlib, X Protocol, Icccm, Xlfd, 3rd edition.", Digital
- Press ISBN 1555580882, Feburary 1992.
-
- [POSIX] ISO/IEC, 9945-1., "Information technology -- Portable
- Operating System Interface (POSIX)-Part 1: System
- Application Program Interface (API) C Language", ANSI/IEE
- Std 1003.1, July 1996.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park CA 94025
- USA
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Connection Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
deleted file mode 100644
index 06c91bf8cd..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.2.ps
+++ /dev/null
@@ -1,2853 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:26:07 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft S. Lehtinen) s
-5 679 M
-(Expires: April 1, 2002 SSH Communications Security Corp) s
-5 668 M
-( October 2001) s
-5 635 M
-( SSH File Transfer Protocol) s
-5 624 M
-( draft-ietf-secsh-filexfer-02.txt) s
-5 602 M
-(Status of this Memo) s
-5 580 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 569 M
-( all provisions of Section 10 of RFC2026.) s
-5 547 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 536 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 525 M
-( other groups may also distribute working documents as Internet-) s
-5 514 M
-( Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on April 1, 2002.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 272 M
-( functionality over any reliable data stream. It is the standard file) s
-5 261 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 250 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 239 M
-( protocol suite.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8) s
-5 613 M
-( 6. Requests From the Client to the Server . . . . . . . . . . . 10) s
-5 602 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10) s
-5 591 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 580 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11) s
-5 569 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13) s
-5 558 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14) s
-5 547 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15) s
-5 536 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15) s
-5 525 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16) s
-5 514 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17) s
-5 503 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18) s
-5 492 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18) s
-5 481 M
-( 7. Responses from the Server to the Client . . . . . . . . . . 20) s
-5 470 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24) s
-5 459 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . . 25) s
-5 448 M
-( 10. Changes from previous protocol versions . . . . . . . . . . 26) s
-5 437 M
-( 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26) s
-5 426 M
-( 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26) s
-5 415 M
-( 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26) s
-5 404 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 393 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . . 28) s
-5 382 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28) s
-5 371 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . . 29) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [3].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft.[3].) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [5] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The following values are defined for packet types.) s
-5 668 M
-( #define SSH_FXP_INIT 1) s
-5 657 M
-( #define SSH_FXP_VERSION 2) s
-5 646 M
-( #define SSH_FXP_OPEN 3) s
-5 635 M
-( #define SSH_FXP_CLOSE 4) s
-5 624 M
-( #define SSH_FXP_READ 5) s
-5 613 M
-( #define SSH_FXP_WRITE 6) s
-5 602 M
-( #define SSH_FXP_LSTAT 7) s
-5 591 M
-( #define SSH_FXP_FSTAT 8) s
-5 580 M
-( #define SSH_FXP_SETSTAT 9) s
-5 569 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 558 M
-( #define SSH_FXP_OPENDIR 11) s
-5 547 M
-( #define SSH_FXP_READDIR 12) s
-5 536 M
-( #define SSH_FXP_REMOVE 13) s
-5 525 M
-( #define SSH_FXP_MKDIR 14) s
-5 514 M
-( #define SSH_FXP_RMDIR 15) s
-5 503 M
-( #define SSH_FXP_REALPATH 16) s
-5 492 M
-( #define SSH_FXP_STAT 17) s
-5 481 M
-( #define SSH_FXP_RENAME 18) s
-5 470 M
-( #define SSH_FXP_READLINK 19) s
-5 459 M
-( #define SSH_FXP_SYMLINK 20) s
-5 448 M
-( #define SSH_FXP_STATUS 101) s
-5 437 M
-( #define SSH_FXP_HANDLE 102) s
-5 426 M
-( #define SSH_FXP_DATA 103) s
-5 415 M
-( #define SSH_FXP_NAME 104) s
-5 404 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( Additional packet types should only be defined if the protocol) s
-5 349 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 338 M
-( incremented, and their use MUST be negotiated using the version) s
-5 327 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 316 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 305 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, it first sends a SSH_FXP_INIT) s
-5 657 M
-( \(including its version number\) packet to the server. The server) s
-5 646 M
-( responds with a SSH_FXP_VERSION packet, supplying the lowest of its) s
-5 635 M
-( own and the client's version number. Both parties should from then) s
-5 624 M
-( on adhere to particular version of the protocol.) s
-5 602 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 591 M
-( data:) s
-5 569 M
-( uint32 version) s
-5 558 M
-( <extension data>) s
-5 536 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 492 M
-( <extension data>) s
-5 470 M
-( The version number of the protocol specified in this document is 3.) s
-5 459 M
-( The version number should be incremented for each incompatible) s
-5 448 M
-( revision of this protocol.) s
-5 426 M
-( The extension data in the above packets may be empty, or may be a) s
-5 415 M
-( sequence of) s
-5 393 M
-( string extension_name) s
-5 382 M
-( string extension_data) s
-5 360 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 349 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 338 M
-( strings indicate extensions to the baseline protocol. The) s
-5 327 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 316 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 305 M
-( domain name of the organization defining the extension. Additional) s
-5 294 M
-( names that are not of this format may be defined later by the IETF.) s
-5 283 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 272 M
-( do not recognize.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes. It) s
-5 657 M
-( is basically just a combination of elementary types, but is defined) s
-5 646 M
-( once because of the non-trivial description of the fields and to) s
-5 635 M
-( ensure maintainability.) s
-5 613 M
-( The same encoding is used both when returning file attributes from) s
-5 602 M
-( the server and when sending file attributes to the server. When) s
-5 591 M
-( sending it to the server, the flags field specifies which attributes) s
-5 580 M
-( are included, and the server will use default values for the) s
-5 569 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 558 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 547 M
-( specify which attributes are included in the returned data. The) s
-5 536 M
-( server normally returns all attributes it knows about.) s
-5 514 M
-( uint32 flags) s
-5 503 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 492 M
-( uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 481 M
-( uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID) s
-5 470 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 459 M
-( uint32 atime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 448 M
-( uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME) s
-5 437 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 426 M
-( string extended_type) s
-5 415 M
-( string extended_data) s
-5 404 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 393 M
-( so that number of pairs equals extended_count) s
-5 371 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 360 M
-( for which the corresponding flag is not set are not present \(not) s
-5 349 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 338 M
-( the protocol version number \(or by using the extension mechanism) s
-5 327 M
-( described below\).) s
-5 305 M
-( The `size' field specifies the size of the file in bytes.) s
-5 283 M
-( The `uid' and `gid' fields contain numeric Unix-like user and group) s
-5 272 M
-( identifiers, respectively.) s
-5 250 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 239 M
-( defined by posix [1].) s
-5 217 M
-( The `atime' and `mtime' contain the access and modification times of) s
-5 206 M
-( the files, respectively. They are represented as seconds from Jan 1,) s
-5 195 M
-( 1970 in UTC.) s
-5 173 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 679 M
-( then the `extended_count' field is present. It specifies the number) s
-5 668 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 657 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 646 M
-( the extended_type field should be a string of the format) s
-5 635 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 624 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 613 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 602 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 591 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 580 M
-( do not understand.) s
-5 558 M
-( Additional fields can be added to the attributes by either defining) s
-5 547 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 536 M
-( defining extended attributes for them. The extended attributes) s
-5 525 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 514 M
-( should only be defined by an IETF standards action that also) s
-5 503 M
-( increments the protocol version number. The use of such new fields) s
-5 492 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 481 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 470 M
-( received.) s
-5 448 M
-( The flags bits are defined to have the following values:) s
-5 426 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 415 M
-( #define SSH_FILEXFER_ATTR_UIDGID 0x00000002) s
-5 404 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 393 M
-( #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008) s
-5 382 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation of it is a monotonically increasing) s
-5 613 M
-( request sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( It is understood that the lack of well-defined semantics for file) s
-5 382 M
-( names may cause interoperability problems between clients and servers) s
-5 371 M
-( using radically different operating systems. However, this approach) s
-5 360 M
-( is known to work acceptably with most systems, and alternative) s
-5 349 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 338 M
-( components are quite complicated.) s
-5 316 M
-(6.3 Opening, Creating, and Closing Files) s
-5 294 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 283 M
-( data part is as follows:) s
-5 261 M
-( uint32 id) s
-5 250 M
-( string filename) s
-5 239 M
-( uint32 pflags) s
-5 228 M
-( ATTRS attrs) s
-5 206 M
-( The `id' field is the request identifier as for all requests.) s
-5 184 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 173 M
-( Names'' for more information.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 679 M
-( defined.) s
-5 657 M
-( #define SSH_FXF_READ 0x00000001) s
-5 646 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 635 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 624 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 613 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 602 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 580 M
-( These have the following meanings:) s
-5 558 M
-( SSH_FXF_READ) s
-5 547 M
-( Open the file for reading.) s
-5 525 M
-( SSH_FXF_WRITE) s
-5 514 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 503 M
-( specified, the file is opened for both reading and writing.) s
-5 481 M
-( SSH_FXF_APPEND) s
-5 470 M
-( Force all writes to append data at the end of the file.) s
-5 448 M
-( SSH_FXF_CREAT) s
-5 437 M
-( If this flag is specified, then a new file will be created if one) s
-5 426 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 415 M
-( be truncated to zero length if it previously exists\).) s
-5 393 M
-( SSH_FXF_TRUNC) s
-5 382 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 371 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 360 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 338 M
-( SSH_FXF_EXCL) s
-5 327 M
-( Causes the request to fail if the named file already exists.) s
-5 316 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 294 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 283 M
-( Default values will be used for those attributes that are not) s
-5 272 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 250 M
-( Regardless the server operating system, the file will always be) s
-5 239 M
-( opened in "binary" mode \(i.e., no translations between different) s
-5 228 M
-( character sets and newline encodings\).) s
-5 206 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 195 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 679 M
-( has the following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string handle) s
-5 624 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 613 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 602 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 591 M
-( request has been sent.) s
-5 569 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 558 M
-( should note that on some server platforms even a close can fail.) s
-5 547 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 536 M
-( and an error occurs while flushing cached writes during the close.) s
-5 514 M
-(6.4 Reading and Writing) s
-5 492 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 481 M
-( message, which has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 437 M
-( uint64 offset) s
-5 426 M
-( uint32 len) s
-5 404 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 393 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 382 M
-( to the beginning of the file from where to start reading, and `len') s
-5 371 M
-( is the maximum number of bytes to read.) s
-5 349 M
-( In response to this request, the server will read as many bytes as it) s
-5 338 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 327 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 316 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 305 M
-( files, it is guaranteed that this will read the specified number of) s
-5 294 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 283 M
-( fewer bytes than requested.) s
-5 261 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 250 M
-( has the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string handle) s
-5 206 M
-( uint64 offset) s
-5 195 M
-( string data) s
-5 173 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 679 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 668 M
-( to be written.) s
-5 646 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 635 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 624 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 613 M
-( and then the data. On most operating systems, such writes do not) s
-5 602 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 580 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 558 M
-(6.5 Removing and Renaming Files) s
-5 536 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 525 M
-( following format:) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string filename) s
-5 470 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 459 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 448 M
-( information. This request cannot be used to remove directories.) s
-5 426 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 415 M
-( message.) s
-5 393 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 382 M
-( message. Its data is as follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( string oldpath) s
-5 338 M
-( string newpath) s
-5 316 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 305 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 294 M
-( file or directory. It is an error if there already exists a file) s
-5 283 M
-( with the name specified by newpath. The server may also fail rename) s
-5 272 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 261 M
-( point to different file systems on the server.) s
-5 239 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 228 M
-( message.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(6.6 Creating and Deleting Directories) s
-5 668 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 657 M
-( has the following format:) s
-5 635 M
-( uint32 id) s
-5 624 M
-( string path) s
-5 613 M
-( ATTRS attrs) s
-5 591 M
-( where `id' is the request identifier, `path' and `attrs' specifies) s
-5 580 M
-( the modifications to be made to its attributes. See Section ``File) s
-5 569 M
-( Names'' for more information on file names. Attributes are discussed) s
-5 558 M
-( in more detail in Section ``File Attributes''. specifies the) s
-5 547 M
-( directory to be created. An error will be returned if a file or) s
-5 536 M
-( directory with the specified path already exists. The server will) s
-5 525 M
-( respond to this request with a SSH_FXP_STATUS message.) s
-5 503 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which) s
-5 492 M
-( has the following format:) s
-5 470 M
-( uint32 id) s
-5 459 M
-( string path) s
-5 437 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 426 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 415 M
-( information on file names. An error will be returned if no directory) s
-5 404 M
-( with the specified path exists, or if the specified directory is not) s
-5 393 M
-( empty, or if the path specified a file system object other than a) s
-5 382 M
-( directory. The server responds to this request with a SSH_FXP_STATUS) s
-5 371 M
-( message.) s
-5 349 M
-(6.7 Scanning Directories) s
-5 327 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 316 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 305 M
-( or more file names with full file attributes for each file. The) s
-5 294 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 283 M
-( file it is looking for or until the server responds with a) s
-5 272 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 261 M
-( there are no more files in the directory\). The client should then) s
-5 250 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 679 M
-( following format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path) s
-5 624 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 613 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 602 M
-( ``File Names'' for more information on file names. This will return) s
-5 591 M
-( an error if the path does not specify a directory or if the directory) s
-5 580 M
-( is not readable. The server will respond to this request with either) s
-5 569 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 547 M
-( Once the directory has been successfully opened, files \(and) s
-5 536 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 525 M
-( requests. These are of the format) s
-5 503 M
-( uint32 id) s
-5 492 M
-( string handle) s
-5 470 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 459 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 448 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 426 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 415 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 404 M
-( Full status information is returned for each name in order to speed) s
-5 393 M
-( up typical directory listings.) s
-5 371 M
-( When the client no longer wishes to read more names from the) s
-5 360 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 349 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 327 M
-(6.8 Retrieving File Attributes) s
-5 305 M
-( Very often, file attributes are automatically returned by) s
-5 294 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 283 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 272 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 250 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 239 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 228 M
-( follow symbolic links. Both have the same format:) s
-5 206 M
-( uint32 id) s
-5 195 M
-( string path) s
-5 173 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( system object for which status is to be returned. The server) s
-5 679 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 657 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 646 M
-( information for an open file \(identified by the file handle\). Its) s
-5 635 M
-( format is as follows:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string handle) s
-5 580 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 569 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 558 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 536 M
-(6.9 Setting File Attributes) s
-5 514 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 503 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 492 M
-( such as changing the ownership, permissions or access times, as well) s
-5 481 M
-( as for truncating a file.) s
-5 459 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string path) s
-5 415 M
-( ATTRS attrs) s
-5 393 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 382 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 371 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 360 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 349 M
-( ``File Attributes''.) s
-5 327 M
-( An error will be returned if the specified file system object does) s
-5 316 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 305 M
-( specified attributes. The server responds to this request with a) s
-5 294 M
-( SSH_FXP_STATUS message.) s
-5 272 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 261 M
-( is already open. It has the following format:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string handle) s
-5 217 M
-( ATTRS attrs) s
-5 195 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 184 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 173 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 679 M
-( ``File Attributes''. The server will respond to this request with) s
-5 668 M
-( SSH_FXP_STATUS.) s
-5 646 M
-(6.10 Dealing with Symbolic links) s
-5 624 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 613 M
-( symbolic link. It would have a data part as follows:) s
-5 591 M
-( uint32 id) s
-5 580 M
-( string path) s
-5 558 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 547 M
-( name of the symlink to be read.) s
-5 525 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 514 M
-( one name and a dummy attributes value. The name in the returned) s
-5 503 M
-( packet contains the target of the link. If an error occurs, the) s
-5 492 M
-( server may respond with SSH_FXP_STATUS.) s
-5 470 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 459 M
-( server. It is of the following format) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string linkpath) s
-5 415 M
-( string targetpath) s
-5 393 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 382 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 371 M
-( target of the symlink. The server shall respond with a) s
-5 360 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 349 M
-( condition.) s
-5 327 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 305 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 294 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 283 M
-( for converting path names containing ".." components or relative) s
-5 272 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 261 M
-( the request is as follows:) s
-5 239 M
-( uint32 id) s
-5 228 M
-( string path) s
-5 206 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 195 M
-( name to be canonicalized. The server will respond with a) s
-5 184 M
-( SSH_FXP_NAME packet containing only one name and a dummy attributes) s
-5 173 M
-( value. The name is the returned packet will be in canonical form.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( If an error occurs, the server may also respond with SSH_FXP_STATUS.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( Currently, the following values are defined \(other values may be) s
-5 679 M
-( defined by future versions of this protocol\):) s
-5 657 M
-( #define SSH_FX_OK 0) s
-5 646 M
-( #define SSH_FX_EOF 1) s
-5 635 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 624 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 613 M
-( #define SSH_FX_FAILURE 4) s
-5 602 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 591 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 580 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 569 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 547 M
-( SSH_FX_OK) s
-5 536 M
-( Indicates successful completion of the operation.) s
-5 514 M
-( SSH_FX_EOF) s
-5 503 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 492 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 481 M
-( indicates that no more files are contained in the directory.) s
-5 459 M
-( SSH_FX_NO_SUCH_FILE) s
-5 448 M
-( is returned when a reference is made to a file which should exist) s
-5 437 M
-( but doesn't.) s
-5 415 M
-( SSH_FX_PERMISSION_DENIED) s
-5 404 M
-( is returned when the authenticated user does not have sufficient) s
-5 393 M
-( permissions to perform the operation.) s
-5 371 M
-( SSH_FX_FAILURE) s
-5 360 M
-( is a generic catch-all error message; it should be returned if an) s
-5 349 M
-( error occurs for which there is no more specific error code) s
-5 338 M
-( defined.) s
-5 316 M
-( SSH_FX_BAD_MESSAGE) s
-5 305 M
-( may be returned if a badly formatted packet or protocol) s
-5 294 M
-( incompatibility is detected.) s
-5 272 M
-( SSH_FX_NO_CONNECTION) s
-5 261 M
-( is a pseudo-error which indicates that the client has no) s
-5 250 M
-( connection to the server \(it can only be generated locally by the) s
-5 239 M
-( client, and MUST NOT be returned by servers\).) s
-5 217 M
-( SSH_FX_CONNECTION_LOST) s
-5 206 M
-( is a pseudo-error which indicates that the connection to the) s
-5 195 M
-( server has been lost \(it can only be generated locally by the) s
-5 184 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 580 M
-( uint32 id) s
-5 569 M
-( string handle) s
-5 547 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 536 M
-( string that identifies an open file or directory on the server. The) s
-5 525 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 514 M
-( interpret or modify it in any way. The length of the handle string) s
-5 503 M
-( MUST NOT exceed 256 data bytes.) s
-5 481 M
-( The SSH_FXP_DATA response has the following format:) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string data) s
-5 426 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 415 M
-( string containing the requested data. The data string may be at most) s
-5 404 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 393 M
-( be shorter if end of file is reached or if the read is from something) s
-5 382 M
-( other than a regular file.) s
-5 360 M
-( The SSH_FXP_NAME response has the following format:) s
-5 338 M
-( uint32 id) s
-5 327 M
-( uint32 count) s
-5 316 M
-( repeats count times:) s
-5 305 M
-( string filename) s
-5 294 M
-( string longname) s
-5 283 M
-( ATTRS attrs) s
-5 261 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 250 M
-( returned in this response, and the remaining fields repeat `count') s
-5 239 M
-( times \(so that all three fields are first included for the first) s
-5 228 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 217 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 206 M
-( will be a relative name within the directory, without any path) s
-5 195 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 184 M
-( `longname' is an expanded format for the file name, similar to what) s
-5 173 M
-( is returned by "ls -l" on Unix systems, and `attrs' is the attributes) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-( of the file as described in Section ``File Attributes''.) s
-5 668 M
-( The format of the `longname' field is unspecified by this protocol.) s
-5 657 M
-( It MUST be suitable for use in the output of a directory listing) s
-5 646 M
-( command \(in fact, the recommended operation for a directory listing) s
-5 635 M
-( command is to simply display this data\). However, clients SHOULD NOT) s
-5 624 M
-( attempt to parse the longname field for file attributes; they SHOULD) s
-5 613 M
-( use the attrs field instead.) s
-5 591 M
-( The recommended format for the longname field is as follows:) s
-5 569 M
-( -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer) s
-5 558 M
-( 1234567890 123 12345678 12345678 12345678 123456789012) s
-5 536 M
-( Here, the first line is sample output, and the second field indicates) s
-5 525 M
-( widths of the various fields. Fields are separated by spaces. The) s
-5 514 M
-( first field lists file permissions for user, group, and others; the) s
-5 503 M
-( second field is link count; the third field is the name of the user) s
-5 492 M
-( who owns the file; the fourth field is the name of the group that) s
-5 481 M
-( owns the file; the fifth field is the size of the file in bytes; the) s
-5 470 M
-( sixth field \(which actually may contain spaces, but is fixed to 12) s
-5 459 M
-( characters\) is the file modification time, and the seventh field is) s
-5 448 M
-( the file name. Each field is specified to be a minimum of certain) s
-5 437 M
-( number of character positions \(indicated by the second line above\),) s
-5 426 M
-( but may also be longer if the data does not fit in the specified) s
-5 415 M
-( length.) s
-5 393 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ATTRS attrs) s
-5 338 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 327 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [6].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 3 and 2) s
-5 602 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 580 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 569 M
-( added.) s
-5 547 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 536 M
-( message' and `language tag'.) s
-5 503 M
-(10.2 Changes between versions 2 and 1) s
-5 481 M
-( o The SSH_FXP_RENAME message was added.) s
-5 448 M
-(10.3 Changes between versions 1 and 0) s
-5 426 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Institute of Electrical and Electronics Engineers, "Information) s
-5 613 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 602 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 591 M
-( IEEE Standard 1003.2, 1996.) s
-5 569 M
-( [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 558 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 547 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 525 M
-( [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 514 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 503 M
-( architecture-09 \(work in progress\), July 2001.) s
-5 481 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 470 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11) s
-5 459 M
-( \(work in progress\), July 2001.) s
-5 437 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 426 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 415 M
-( userauth-11 \(work in progress\), July 2001.) s
-5 382 M
-(Authors' Addresses) s
-5 360 M
-( Tatu Ylonen) s
-5 349 M
-( SSH Communications Security Corp) s
-5 338 M
-( Fredrikinkatu 42) s
-5 327 M
-( HELSINKI FIN-00100) s
-5 316 M
-( Finland) s
-5 294 M
-( EMail: [email protected]) s
-5 261 M
-( Sami Lehtinen) s
-5 250 M
-( SSH Communications Security Corp) s
-5 239 M
-( Fredrikinkatu 42) s
-5 228 M
-( HELSINKI FIN-00100) s
-5 217 M
-( Finland) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2001) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2001\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Lehtinen Expires April 1, 2002 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 30
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
deleted file mode 100644
index c4ec8c1125..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-02.txt
+++ /dev/null
@@ -1,1627 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft S. Lehtinen
-Expires: April 1, 2002 SSH Communications Security Corp
- October 2001
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-02.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 1, 2002.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . . 7
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . . 8
- 6. Requests From the Client to the Server . . . . . . . . . . . 10
- 6.1 Request Synchronization and Reordering . . . . . . . . . . . 10
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . . 11
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . . 13
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . . 14
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . . 15
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . . 15
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . . 16
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . . 17
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . . 18
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . . 18
- 7. Responses from the Server to the Client . . . . . . . . . . 20
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . . 24
- 9. Security Considerations . . . . . . . . . . . . . . . . . . 25
- 10. Changes from previous protocol versions . . . . . . . . . . 26
- 10.1 Changes between versions 3 and 2 . . . . . . . . . . . . . . 26
- 10.2 Changes between versions 2 and 1 . . . . . . . . . . . . . . 26
- 10.3 Changes between versions 1 and 0 . . . . . . . . . . . . . . 26
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . . 27
- References . . . . . . . . . . . . . . . . . . . . . . . . . 28
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 28
- Full Copyright Statement . . . . . . . . . . . . . . . . . . 29
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [3].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft.[3].
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [5] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The following values are defined for packet types.
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, it first sends a SSH_FXP_INIT
- (including its version number) packet to the server. The server
- responds with a SSH_FXP_VERSION packet, supplying the lowest of its
- own and the client's version number. Both parties should from then
- on adhere to particular version of the protocol.
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
- <extension data>
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- The version number of the protocol specified in this document is 3.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
- The extension data in the above packets may be empty, or may be a
- sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes. It
- is basically just a combination of elementary types, but is defined
- once because of the non-trivial description of the fields and to
- ensure maintainability.
-
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- uint32 uid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 gid present only if flag SSH_FILEXFER_ATTR_UIDGID
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 mtime present only if flag SSH_FILEXFER_ACMODTIME
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The `size' field specifies the size of the file in bytes.
-
- The `uid' and `gid' fields contain numeric Unix-like user and group
- identifiers, respectively.
-
- The `permissions' field contains a bit mask of file permissions as
- defined by posix [1].
-
- The `atime' and `mtime' contain the access and modification times of
- the files, respectively. They are represented as seconds from Jan 1,
- 1970 in UTC.
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation of it is a monotonically increasing
- request sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
- uint32 id
- string filename
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
- Regardless the server operating system, the file will always be
- opened in "binary" mode (i.e., no translations between different
- character sets and newline encodings).
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath
- string newpath
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' and `attrs' specifies
- the modifications to be made to its attributes. See Section ``File
- Names'' for more information on file names. Attributes are discussed
- in more detail in Section ``File Attributes''. specifies the
- directory to be created. An error will be returned if a file or
- directory with the specified path already exists. The server will
- respond to this request with a SSH_FXP_STATUS message.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which
- has the following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names. An error will be returned if no directory
- with the specified path exists, or if the specified directory is not
- empty, or if the path specified a file system object other than a
- directory. The server responds to this request with a SSH_FXP_STATUS
- message.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path
-
- where `id' is the request identifier, and `path' specifies the file
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath
- string targetpath
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing only one name and a dummy attributes
- value. The name is the returned packet will be in canonical form.
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- If an error occurs, the server may also respond with SSH_FXP_STATUS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which should exist
- but doesn't.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename
- string longname
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- `longname' is an expanded format for the file name, similar to what
- is returned by "ls -l" on Unix systems, and `attrs' is the attributes
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
- of the file as described in Section ``File Attributes''.
-
- The format of the `longname' field is unspecified by this protocol.
- It MUST be suitable for use in the output of a directory listing
- command (in fact, the recommended operation for a directory listing
- command is to simply display this data). However, clients SHOULD NOT
- attempt to parse the longname field for file attributes; they SHOULD
- use the attrs field instead.
-
- The recommended format for the longname field is as follows:
-
- -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
- 1234567890 123 12345678 12345678 12345678 123456789012
-
- Here, the first line is sample output, and the second field indicates
- widths of the various fields. Fields are separated by spaces. The
- first field lists file permissions for user, group, and others; the
- second field is link count; the third field is the name of the user
- who owns the file; the fourth field is the name of the group that
- owns the file; the fifth field is the size of the file in bytes; the
- sixth field (which actually may contain spaces, but is fixed to 12
- characters) is the file modification time, and the seventh field is
- the file name. Each field is specified to be a minimum of certain
- number of character positions (indicated by the second line above),
- but may also be longer if the data does not fit in the specified
- length.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [6].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.2 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.3 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [3] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [4] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- architecture-09 (work in progress), July 2001.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-11
- (work in progress), July 2001.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-11 (work in progress), July 2001.
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2001
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Lehtinen Expires April 1, 2002 [Page 29]
-
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
deleted file mode 100644
index 6a40cd6067..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.2.ps
+++ /dev/null
@@ -1,3511 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Wed Nov 12 12:18:50 2003
-%%Orientation: Portrait
-%%Pages: 18 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Secure Shell Working Group J. Galbraith) s
-5 690 M
-(Internet-Draft VanDyke Software) s
-5 679 M
-(Expires: April 16, 2003 T. Ylonen) s
-5 668 M
-( S. Lehtinen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( October 16, 2002) s
-5 613 M
-( SSH File Transfer Protocol) s
-5 602 M
-( draft-ietf-secsh-filexfer-03.txt) s
-5 580 M
-(Status of this Memo) s
-5 558 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 547 M
-( all provisions of Section 10 of RFC2026.) s
-5 525 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 514 M
-( Task Force \(IETF\), its areas, and its working groups. Note that) s
-5 503 M
-( other groups may also distribute working documents as Internet-) s
-5 492 M
-( Drafts.) s
-5 470 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 459 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 448 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 437 M
-( material or to cite them other than as "work in progress.") s
-5 415 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 404 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 382 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 371 M
-( http://www.ietf.org/shadow.html.) s
-5 349 M
-( This Internet-Draft will expire on April 16, 2003.) s
-5 327 M
-(Copyright Notice) s
-5 305 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 283 M
-(Abstract) s
-5 261 M
-( The SSH File Transfer Protocol provides secure file transfer) s
-5 250 M
-( functionality over any reliable data stream. It is the standard file) s
-5 239 M
-( transfer protocol for use with the SSH2 protocol. This document) s
-5 228 M
-( describes the file transfer protocol and its interface to the SSH2) s
-5 217 M
-( protocol suite.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4) s
-5 646 M
-( 3. General Packet Format . . . . . . . . . . . . . . . . . . 5) s
-5 635 M
-( 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7) s
-5 624 M
-( 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 613 M
-( 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7) s
-5 602 M
-( 4.3 Determining Server Newline Convention . . . . . . . . . . 8) s
-5 591 M
-( 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9) s
-5 580 M
-( 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 569 M
-( 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 558 M
-( 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10) s
-5 547 M
-( 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10) s
-5 536 M
-( 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 525 M
-( 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 514 M
-( 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11) s
-5 503 M
-( 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12) s
-5 492 M
-( 6. Requests From the Client to the Server . . . . . . . . . . 13) s
-5 481 M
-( 6.1 Request Synchronization and Reordering . . . . . . . . . . 13) s
-5 470 M
-( 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14) s
-5 459 M
-( 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14) s
-5 448 M
-( 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17) s
-5 437 M
-( 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18) s
-5 426 M
-( 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19) s
-5 415 M
-( 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19) s
-5 404 M
-( 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20) s
-5 393 M
-( 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21) s
-5 382 M
-( 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22) s
-5 371 M
-( 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23) s
-5 360 M
-( 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23) s
-5 349 M
-( 7. Responses from the Server to the Client . . . . . . . . . 24) s
-5 338 M
-( 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28) s
-5 327 M
-( 9. Security Considerations . . . . . . . . . . . . . . . . . 29) s
-5 316 M
-( 10. Changes from previous protocol versions . . . . . . . . . 30) s
-5 305 M
-( 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30) s
-5 294 M
-( 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31) s
-5 283 M
-( 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31) s
-5 272 M
-( 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31) s
-5 261 M
-( 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32) s
-5 250 M
-( References . . . . . . . . . . . . . . . . . . . . . . . . 33) s
-5 239 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33) s
-5 228 M
-( Full Copyright Statement . . . . . . . . . . . . . . . . . 35) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(1. Introduction) s
-5 668 M
-( This protocol provides secure file transfer \(and more generally file) s
-5 657 M
-( system access\) functionality over a reliable data stream, such as a) s
-5 646 M
-( channel in the SSH2 protocol [5].) s
-5 624 M
-( This protocol is designed so that it could be used to implement a) s
-5 613 M
-( secure remote file system service, as well as a secure file transfer) s
-5 602 M
-( service.) s
-5 580 M
-( This protocol assumes that it runs over a secure channel, and that) s
-5 569 M
-( the server has already authenticated the user at the client end, and) s
-5 558 M
-( that the identity of the client user is externally available to the) s
-5 547 M
-( server implementation.) s
-5 525 M
-( In general, this protocol follows a simple request-response model.) s
-5 514 M
-( Each request and response contains a sequence number and multiple) s
-5 503 M
-( requests may be pending simultaneously. There are a relatively large) s
-5 492 M
-( number of different request messages, but a small number of possible) s
-5 481 M
-( response messages. Each request has one or more response messages) s
-5 470 M
-( that may be returned in result \(e.g., a read either returns data or) s
-5 459 M
-( reports error status\).) s
-5 437 M
-( The packet format descriptions in this specification follow the) s
-5 426 M
-( notation presented in the secsh architecture draft. [5]) s
-5 404 M
-( Even though this protocol is described in the context of the SSH2) s
-5 393 M
-( protocol, this protocol is general and independent of the rest of the) s
-5 382 M
-( SSH2 protocol suite. It could be used in a number of different) s
-5 371 M
-( applications, such as secure file transfer over TLS RFC 2246 [1] and) s
-5 360 M
-( transfer of management information in VPN applications.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(2. Use with the SSH Connection Protocol) s
-5 668 M
-( When used with the SSH2 Protocol suite, this protocol is intended to) s
-5 657 M
-( be used from the SSH Connection Protocol [7] as a subsystem, as) s
-5 646 M
-( described in section ``Starting a Shell or a Command''. The) s
-5 635 M
-( subsystem name used with this protocol is "sftp".) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(3. General Packet Format) s
-5 668 M
-( All packets transmitted over the secure connection are of the) s
-5 657 M
-( following format:) s
-5 635 M
-( uint32 length) s
-5 624 M
-( byte type) s
-5 613 M
-( byte[length - 1] data payload) s
-5 591 M
-( That is, they are just data preceded by 32-bit length and 8-bit type) s
-5 580 M
-( fields. The `length' is the length of the data area, and does not) s
-5 569 M
-( include the `length' field itself. The format and interpretation of) s
-5 558 M
-( the data area depends on the packet type.) s
-5 536 M
-( All packet descriptions below only specify the packet type and the) s
-5 525 M
-( data that goes into the data field. Thus, they should be prefixed by) s
-5 514 M
-( the `length' and `type' fields.) s
-5 492 M
-( The maximum size of a packet is in practice determined by the client) s
-5 481 M
-( \(the maximum size of read or write requests that it sends, plus a few) s
-5 470 M
-( bytes of packet overhead\). All servers SHOULD support packets of at) s
-5 459 M
-( least 34000 bytes \(where the packet size refers to the full length,) s
-5 448 M
-( including the header above\). This should allow for reads and writes) s
-5 437 M
-( of at most 32768 bytes.) s
-5 415 M
-( There is no limit on the number of outstanding \(non-acknowledged\)) s
-5 404 M
-( requests that the client may send to the server. In practice this is) s
-5 393 M
-( limited by the buffering available on the data stream and the queuing) s
-5 382 M
-( performed by the server. If the server's queues are full, it should) s
-5 371 M
-( not read any more data from the stream, and flow control will prevent) s
-5 360 M
-( the client from sending more requests. Note, however, that while) s
-5 349 M
-( there is no restriction on the protocol level, the client's API may) s
-5 338 M
-( provide a limit in order to prevent infinite queuing of outgoing) s
-5 327 M
-( requests at the client.) s
-5 305 M
-( The following values are defined for packet types.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FXP_INIT 1) s
-5 679 M
-( #define SSH_FXP_VERSION 2) s
-5 668 M
-( #define SSH_FXP_OPEN 3) s
-5 657 M
-( #define SSH_FXP_CLOSE 4) s
-5 646 M
-( #define SSH_FXP_READ 5) s
-5 635 M
-( #define SSH_FXP_WRITE 6) s
-5 624 M
-( #define SSH_FXP_LSTAT 7) s
-5 613 M
-( #define SSH_FXP_FSTAT 8) s
-5 602 M
-( #define SSH_FXP_SETSTAT 9) s
-5 591 M
-( #define SSH_FXP_FSETSTAT 10) s
-5 580 M
-( #define SSH_FXP_OPENDIR 11) s
-5 569 M
-( #define SSH_FXP_READDIR 12) s
-5 558 M
-( #define SSH_FXP_REMOVE 13) s
-5 547 M
-( #define SSH_FXP_MKDIR 14) s
-5 536 M
-( #define SSH_FXP_RMDIR 15) s
-5 525 M
-( #define SSH_FXP_REALPATH 16) s
-5 514 M
-( #define SSH_FXP_STAT 17) s
-5 503 M
-( #define SSH_FXP_RENAME 18) s
-5 492 M
-( #define SSH_FXP_READLINK 19) s
-5 481 M
-( #define SSH_FXP_SYMLINK 20) s
-5 459 M
-( #define SSH_FXP_STATUS 101) s
-5 448 M
-( #define SSH_FXP_HANDLE 102) s
-5 437 M
-( #define SSH_FXP_DATA 103) s
-5 426 M
-( #define SSH_FXP_NAME 104) s
-5 415 M
-( #define SSH_FXP_ATTRS 105) s
-5 393 M
-( #define SSH_FXP_EXTENDED 200) s
-5 382 M
-( #define SSH_FXP_EXTENDED_REPLY 201) s
-5 360 M
-( RESERVED_FOR_EXTENSIONS 210-255) s
-5 338 M
-( Additional packet types should only be defined if the protocol) s
-5 327 M
-( version number \(see Section ``Protocol Initialization''\) is) s
-5 316 M
-( incremented, and their use MUST be negotiated using the version) s
-5 305 M
-( number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY) s
-5 294 M
-( packets can be used to implement vendor-specific extensions. See) s
-5 283 M
-( Section ``Vendor-Specific-Extensions'' for more details.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(4. Protocol Initialization) s
-5 668 M
-( When the file transfer protocol starts, the client first sends a) s
-5 657 M
-( SSH_FXP_INIT \(including its version number\) packet to the server.) s
-5 646 M
-( The server responds with a SSH_FXP_VERSION packet, supplying the) s
-5 635 M
-( lowest of its own and the client's version number. Both parties) s
-5 624 M
-( should from then on adhere to particular version of the protocol.) s
-5 602 M
-( The version number of the protocol specified in this document is 4.) s
-5 591 M
-( The version number should be incremented for each incompatible) s
-5 580 M
-( revision of this protocol.) s
-5 558 M
-(4.1 Client Initialization) s
-5 536 M
-( The SSH_FXP_INIT packet \(from client to server\) has the following) s
-5 525 M
-( data:) s
-5 503 M
-( uint32 version) s
-5 481 M
-( Version 3 of this protocol allowed clients to include extensions in) s
-5 470 M
-( the SSH_FXP_INIT packet; however, this can cause interoperability) s
-5 459 M
-( problems with version 1 and version 2 servers because the client must) s
-5 448 M
-( send this packet before knowing the servers version.) s
-5 426 M
-( In this version of the protocol, clients MUST use the) s
-5 415 M
-( SSH_FXP_EXTENDED packet to send extensions to the server after) s
-5 404 M
-( version exchange has completed. Clients MUST NOT include extensions) s
-5 393 M
-( in the version packet. This will prevent interoperability problems) s
-5 382 M
-( with older servers) s
-5 360 M
-(4.2 Server Initialization) s
-5 338 M
-( The SSH_FXP_VERSION packet \(from server to client\) has the following) s
-5 327 M
-( data:) s
-5 305 M
-( uint32 version) s
-5 294 M
-( <extension data>) s
-5 272 M
-( 'version' is the lower of the protocol version supported by the) s
-5 261 M
-( server and the version number received from the client.) s
-5 239 M
-( The extension data may be empty, or may be a sequence of) s
-5 217 M
-( string extension_name) s
-5 206 M
-( string extension_data) s
-5 184 M
-( pairs \(both strings MUST always be present if one is, but the) s
-5 173 M
-( `extension_data' string may be of zero length\). If present, these) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( strings indicate extensions to the baseline protocol. The) s
-5 679 M
-( `extension_name' field\(s\) identify the name of the extension. The) s
-5 668 M
-( name should be of the form "name@domain", where the domain is the DNS) s
-5 657 M
-( domain name of the organization defining the extension. Additional) s
-5 646 M
-( names that are not of this format may be defined later by the IETF.) s
-5 635 M
-( Implementations MUST silently ignore any extensions whose name they) s
-5 624 M
-( do not recognize.) s
-5 602 M
-(4.3 Determining Server Newline Convention) s
-5 580 M
-( In order to correctly process text files in a cross platform) s
-5 569 M
-( compatible way, the newline convention must be converted from that of) s
-5 558 M
-( the server to that of the client, or, during an upload, from that of) s
-5 547 M
-( the client to that of the server.) s
-5 525 M
-( Versions 3 and prior of this protocol made no provisions for) s
-5 514 M
-( processing text files. Many clients implemented some sort of) s
-5 503 M
-( conversion algorithm, but without either a 'canonical' on the wire) s
-5 492 M
-( format or knowledge of the servers newline convention, correct) s
-5 481 M
-( conversion was not always possible.) s
-5 459 M
-( Starting with Version 4, the SSH_FXF_TEXT file open flag \(Section) s
-5 448 M
-( 6.3\) makes it possible to request that the server translate a file to) s
-5 437 M
-( a 'canonical' on the wire format. This format uses \\r\\n as the line) s
-5 426 M
-( separator.) s
-5 404 M
-( Servers for systems using multiple newline characters \(for example,) s
-5 393 M
-( Mac OS X or VMS\) or systems using counted records, MUST translate to) s
-5 382 M
-( the canonical form.) s
-5 360 M
-( However, to ease the burden of implementation on servers that use a) s
-5 349 M
-( single, simple separator sequence, the following extension allows the) s
-5 338 M
-( canonical format to be changed.) s
-5 316 M
-( string "newline") s
-5 305 M
-( string new-canonical-separator \(usually "\\r" or "\\n" or "\\r\\n"\)) s
-5 283 M
-( All clients MUST support this extension.) s
-5 261 M
-( When processing text files, clients SHOULD NOT translate any) s
-5 250 M
-( character or sequence that is not an exact match of the servers) s
-5 239 M
-( newline separator.) s
-5 217 M
-( In particular, if the newline sequence being used is the canonical) s
-5 206 M
-( "\\r\\n" sequence, a lone \\r or a lone \\n SHOULD be written through) s
-5 195 M
-( without change.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5. File Attributes) s
-5 668 M
-( A new compound data type is defined for encoding file attributes.) s
-5 657 M
-( The same encoding is used both when returning file attributes from) s
-5 646 M
-( the server and when sending file attributes to the server. When) s
-5 635 M
-( sending it to the server, the flags field specifies which attributes) s
-5 624 M
-( are included, and the server will use default values for the) s
-5 613 M
-( remaining attributes \(or will not modify the values of remaining) s
-5 602 M
-( attributes\). When receiving attributes from the server, the flags) s
-5 591 M
-( specify which attributes are included in the returned data. The) s
-5 580 M
-( server normally returns all attributes it knows about.) s
-5 558 M
-( uint32 flags) s
-5 547 M
-( byte type always present) s
-5 536 M
-( uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE) s
-5 525 M
-( string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 514 M
-( string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP) s
-5 503 M
-( uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS) s
-5 492 M
-( uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME) s
-5 481 M
-( uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME) s
-5 470 M
-( uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME) s
-5 459 M
-( string acl present only if flag SSH_FILEXFER_ATTR_ACL) s
-5 448 M
-( uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED) s
-5 437 M
-( string extended_type) s
-5 426 M
-( string extended_data) s
-5 415 M
-( ... more extended data \(extended_type - extended_data pairs\),) s
-5 404 M
-( so that number of pairs equals extended_count) s
-5 371 M
-(5.1 Flags) s
-5 349 M
-( The `flags' specify which of the fields are present. Those fields) s
-5 338 M
-( for which the corresponding flag is not set are not present \(not) s
-5 327 M
-( included in the packet\). New flags can only be added by incrementing) s
-5 316 M
-( the protocol version number \(or by using the extension mechanism) s
-5 305 M
-( described below\).) s
-5 283 M
-( The flags bits are defined to have the following values:) s
-5 261 M
-( #define SSH_FILEXFER_ATTR_SIZE 0x00000001) s
-5 250 M
-( #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004) s
-5 239 M
-( #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008) s
-5 228 M
-( #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010) s
-5 217 M
-( #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020) s
-5 206 M
-( #define SSH_FILEXFER_ATTR_ACL 0x00000040) s
-5 195 M
-( #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080) s
-5 184 M
-( #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( In previous versions of this protocol flags value 0x00000002 was) s
-5 679 M
-( SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP) s
-5 668 M
-( was given a new value in order to ease implementation burden.) s
-5 657 M
-( 0x00000002 MUST NOT appear in the mask. Some future version of this) s
-5 646 M
-( protocol may reuse flag 0x00000002.) s
-5 624 M
-(5.2 Type) s
-5 602 M
-( The type field is always present. The following types are defined:) s
-5 580 M
-( #define SSH_FILEXFER_TYPE_REGULAR 1) s
-5 569 M
-( #define SSH_FILEXFER_TYPE_DIRECTORY 2) s
-5 558 M
-( #define SSH_FILEXFER_TYPE_SYMLINK 3) s
-5 547 M
-( #define SSH_FILEXFER_TYPE_SPECIAL 4) s
-5 536 M
-( #define SSH_FILEXFER_TYPE_UNKNOWN 5) s
-5 514 M
-( On a POSIX system, these values would be derived from the permission) s
-5 503 M
-( field.) s
-5 481 M
-(5.3 Size) s
-5 459 M
-( The `size' field specifies the size of the file on disk, in bytes.) s
-5 448 M
-( If it is present during file creation, it should be considered a hint) s
-5 437 M
-( as to the files eventual size.) s
-5 415 M
-( Files opened with the SSH_FXF_TEXT flag may have a size that is) s
-5 404 M
-( greater or less than the value of the size field.) s
-5 382 M
-(5.4 Owner and Group) s
-5 360 M
-( The `owner' and `group' fields are represented as UTF-8 strings; this) s
-5 349 M
-( is the form used by NFS v4. See NFS version 4 Protocol. [3] The) s
-5 338 M
-( following text is selected quotations from section 5.6.) s
-5 316 M
-( To avoid a representation that is tied to a particular underlying) s
-5 305 M
-( implementation at the client or server, the use of UTF-8 strings has) s
-5 294 M
-( been chosen. The string should be of the form user@dns_domain".) s
-5 283 M
-( This will allow for a client and server that do not use the same) s
-5 272 M
-( local representation the ability to translate to a common syntax that) s
-5 261 M
-( can be interpreted by both. In the case where there is no) s
-5 250 M
-( translation available to the client or server, the attribute value) s
-5 239 M
-( must be constructed without the "@". Therefore, the absence of the @) s
-5 228 M
-( from the owner or owner_group attribute signifies that no translation) s
-5 217 M
-( was available and the receiver of the attribute should not place any) s
-5 206 M
-( special meaning with the attribute value. Even though the attribute) s
-5 195 M
-( value can not be translated, it may still be useful. In the case of) s
-5 184 M
-( a client, the attribute string may be used for local display of) s
-5 173 M
-( ownership.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(5.5 Permissions) s
-5 668 M
-( The `permissions' field contains a bit mask of file permissions as) s
-5 657 M
-( defined by POSIX [1].) s
-5 635 M
-(5.6 Times) s
-5 613 M
-( The 'atime', 'createtime', and 'mtime' contain the access, creation,) s
-5 602 M
-( and modification times of the files, respectively. They are) s
-5 591 M
-( represented as seconds from Jan 1, 1970 in UTC.) s
-5 569 M
-(5.7 ACL) s
-5 547 M
-( The 'ACL' field contains an ACL similar to that defined in section) s
-5 536 M
-( 5.9 of NFS version 4 Protocol [3].) s
-5 514 M
-( uint32 ace-count) s
-5 492 M
-( repeated ace-count time:) s
-5 481 M
-( uint32 ace-type) s
-5 470 M
-( uint32 ace-flag) s
-5 459 M
-( uint32 ace-mask) s
-5 448 M
-( string who [UTF-8]) s
-5 426 M
-( ace-type is one of the following four values \(taken from NFS Version) s
-5 415 M
-( 4 Protocol [3]:) s
-5 393 M
-( const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;) s
-5 382 M
-( const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;) s
-5 371 M
-( const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;) s
-5 360 M
-( const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;) s
-5 338 M
-( ace-flag is a combination of the following flag values. See NFS) s
-5 327 M
-( Version 4 Protocol [3] section 5.9.2:) s
-5 305 M
-( const ACE4_FILE_INHERIT_ACE = 0x00000001;) s
-5 294 M
-( const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;) s
-5 283 M
-( const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;) s
-5 272 M
-( const ACE4_INHERIT_ONLY_ACE = 0x00000008;) s
-5 261 M
-( const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;) s
-5 250 M
-( const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;) s
-5 239 M
-( const ACE4_IDENTIFIER_GROUP = 0x00000040;) s
-5 217 M
-( ace-mask is any combination of the following flags \(taken from NFS) s
-5 206 M
-( Version 4 Protocol [3] section 5.9.3:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( const ACE4_READ_DATA = 0x00000001;) s
-5 679 M
-( const ACE4_LIST_DIRECTORY = 0x00000001;) s
-5 668 M
-( const ACE4_WRITE_DATA = 0x00000002;) s
-5 657 M
-( const ACE4_ADD_FILE = 0x00000002;) s
-5 646 M
-( const ACE4_APPEND_DATA = 0x00000004;) s
-5 635 M
-( const ACE4_ADD_SUBDIRECTORY = 0x00000004;) s
-5 624 M
-( const ACE4_READ_NAMED_ATTRS = 0x00000008;) s
-5 613 M
-( const ACE4_WRITE_NAMED_ATTRS = 0x00000010;) s
-5 602 M
-( const ACE4_EXECUTE = 0x00000020;) s
-5 591 M
-( const ACE4_DELETE_CHILD = 0x00000040;) s
-5 580 M
-( const ACE4_READ_ATTRIBUTES = 0x00000080;) s
-5 569 M
-( const ACE4_WRITE_ATTRIBUTES = 0x00000100;) s
-5 558 M
-( const ACE4_DELETE = 0x00010000;) s
-5 547 M
-( const ACE4_READ_ACL = 0x00020000;) s
-5 536 M
-( const ACE4_WRITE_ACL = 0x00040000;) s
-5 525 M
-( const ACE4_WRITE_OWNER = 0x00080000;) s
-5 514 M
-( const ACE4_SYNCHRONIZE = 0x00100000;) s
-5 492 M
-( who is a UTF-8 string of the form described in 'Owner and Group') s
-5 481 M
-( \(Section 5.4\)) s
-5 459 M
-(5.8 Extended attributes) s
-5 437 M
-( The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension) s
-5 426 M
-( mechanism for vendor-specific extensions. If the flag is specified,) s
-5 415 M
-( then the `extended_count' field is present. It specifies the number) s
-5 404 M
-( of extended_type-extended_data pairs that follow. Each of these) s
-5 393 M
-( pairs specifies an extended attribute. For each of the attributes,) s
-5 382 M
-( the extended_type field should be a string of the format) s
-5 371 M
-( "name@domain", where "domain" is a valid, registered domain name and) s
-5 360 M
-( "name" identifies the method. The IETF may later standardize certain) s
-5 349 M
-( names that deviate from this format \(e.g., that do not contain the) s
-5 338 M
-( "@" sign\). The interpretation of `extended_data' depends on the) s
-5 327 M
-( type. Implementations SHOULD ignore extended data fields that they) s
-5 316 M
-( do not understand.) s
-5 294 M
-( Additional fields can be added to the attributes by either defining) s
-5 283 M
-( additional bits to the flags field to indicate their presence, or by) s
-5 272 M
-( defining extended attributes for them. The extended attributes) s
-5 261 M
-( mechanism is recommended for most purposes; additional flags bits) s
-5 250 M
-( should only be defined by an IETF standards action that also) s
-5 239 M
-( increments the protocol version number. The use of such new fields) s
-5 228 M
-( MUST be negotiated by the version number in the protocol exchange.) s
-5 217 M
-( It is a protocol error if a packet with unsupported protocol bits is) s
-5 206 M
-( received.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6. Requests From the Client to the Server) s
-5 668 M
-( Requests from the client to the server represent the various file) s
-5 657 M
-( system operations. Each request begins with an `id' field, which is) s
-5 646 M
-( a 32-bit identifier identifying the request \(selected by the client\).) s
-5 635 M
-( The same identifier will be returned in the response to the request.) s
-5 624 M
-( One possible implementation is a monotonically increasing request) s
-5 613 M
-( sequence number \(modulo 2^32\).) s
-5 591 M
-( Many operations in the protocol operate on open files. The) s
-5 580 M
-( SSH_FXP_OPEN request can return a file handle \(which is an opaque) s
-5 569 M
-( variable-length string\) which may be used to access the file later) s
-5 558 M
-( \(e.g. in a read operation\). The client MUST NOT send requests the) s
-5 547 M
-( server with bogus or closed handles. However, the server MUST) s
-5 536 M
-( perform adequate checks on the handle in order to avoid security) s
-5 525 M
-( risks due to fabricated handles.) s
-5 503 M
-( This design allows either stateful and stateless server) s
-5 492 M
-( implementation, as well as an implementation which caches state) s
-5 481 M
-( between requests but may also flush it. The contents of the file) s
-5 470 M
-( handle string are entirely up to the server and its design. The) s
-5 459 M
-( client should not modify or attempt to interpret the file handle) s
-5 448 M
-( strings.) s
-5 426 M
-( The file handle strings MUST NOT be longer than 256 bytes.) s
-5 404 M
-(6.1 Request Synchronization and Reordering) s
-5 382 M
-( The protocol and implementations MUST process requests relating to) s
-5 371 M
-( the same file in the order in which they are received. In other) s
-5 360 M
-( words, if an application submits multiple requests to the server, the) s
-5 349 M
-( results in the responses will be the same as if it had sent the) s
-5 338 M
-( requests one at a time and waited for the response in each case. For) s
-5 327 M
-( example, the server may process non-overlapping read/write requests) s
-5 316 M
-( to the same file in parallel, but overlapping reads and writes cannot) s
-5 305 M
-( be reordered or parallelized. However, there are no ordering) s
-5 294 M
-( restrictions on the server for processing requests from two different) s
-5 283 M
-( file transfer connections. The server may interleave and parallelize) s
-5 272 M
-( them at will.) s
-5 250 M
-( There are no restrictions on the order in which responses to) s
-5 239 M
-( outstanding requests are delivered to the client, except that the) s
-5 228 M
-( server must ensure fairness in the sense that processing of no) s
-5 217 M
-( request will be indefinitely delayed even if the client is sending) s
-5 206 M
-( other requests so that there are multiple outstanding requests all) s
-5 195 M
-( the time.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(6.2 File Names) s
-5 668 M
-( This protocol represents file names as strings. File names are) s
-5 657 M
-( assumed to use the slash \('/'\) character as a directory separator.) s
-5 635 M
-( File names starting with a slash are "absolute", and are relative to) s
-5 624 M
-( the root of the file system. Names starting with any other character) s
-5 613 M
-( are relative to the user's default directory \(home directory\). Note) s
-5 602 M
-( that identifying the user is assumed to take place outside of this) s
-5 591 M
-( protocol.) s
-5 569 M
-( Servers SHOULD interpret a path name component ".." as referring to) s
-5 558 M
-( the parent directory, and "." as referring to the current directory.) s
-5 547 M
-( If the server implementation limits access to certain parts of the) s
-5 536 M
-( file system, it must be extra careful in parsing file names when) s
-5 525 M
-( enforcing such restrictions. There have been numerous reported) s
-5 514 M
-( security bugs where a ".." in a path name has allowed access outside) s
-5 503 M
-( the intended area.) s
-5 481 M
-( An empty path name is valid, and it refers to the user's default) s
-5 470 M
-( directory \(usually the user's home directory\).) s
-5 448 M
-( Otherwise, no syntax is defined for file names by this specification.) s
-5 437 M
-( Clients should not make any other assumptions; however, they can) s
-5 426 M
-( splice path name components returned by SSH_FXP_READDIR together) s
-5 415 M
-( using a slash \('/'\) as the separator, and that will work as expected.) s
-5 393 M
-( In order to comply with IETF Policy on Character Sets and Languages) s
-5 382 M
-( [2], all filenames are to be encoded in UTF-8. The shortest valid) s
-5 371 M
-( UTF-8 encoding of the UNICODE data MUST be used. The server is) s
-5 360 M
-( responsible for converting the UNICODE data to whatever canonical) s
-5 349 M
-( form it requires.) s
-5 327 M
-( For example, if the server requires that precomposed characters) s
-5 316 M
-( always be used, the server MUST NOT assume the filename as sent by) s
-5 305 M
-( the client has this attribute, but must do this normalization itself.) s
-5 283 M
-( It is understood that the lack of well-defined semantics for file) s
-5 272 M
-( names may cause interoperability problems between clients and servers) s
-5 261 M
-( using radically different operating systems. However, this approach) s
-5 250 M
-( is known to work acceptably with most systems, and alternative) s
-5 239 M
-( approaches that e.g. treat file names as sequences of structured) s
-5 228 M
-( components are quite complicated.) s
-5 206 M
-(6.3 Opening, Creating, and Closing Files) s
-5 184 M
-( Files are opened and created using the SSH_FXP_OPEN message, whose) s
-5 173 M
-( data part is as follows:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string filename [UTF-8]) s
-5 668 M
-( uint32 pflags) s
-5 657 M
-( ATTRS attrs) s
-5 635 M
-( The `id' field is the request identifier as for all requests.) s
-5 613 M
-( The `filename' field specifies the file name. See Section ``File) s
-5 602 M
-( Names'' for more information.) s
-5 580 M
-( The `pflags' field is a bitmask. The following bits have been) s
-5 569 M
-( defined.) s
-5 547 M
-( #define SSH_FXF_READ 0x00000001) s
-5 536 M
-( #define SSH_FXF_WRITE 0x00000002) s
-5 525 M
-( #define SSH_FXF_APPEND 0x00000004) s
-5 514 M
-( #define SSH_FXF_CREAT 0x00000008) s
-5 503 M
-( #define SSH_FXF_TRUNC 0x00000010) s
-5 492 M
-( #define SSH_FXF_EXCL 0x00000020) s
-5 481 M
-( #define SSH_FXF_TEXT 0x00000040) s
-5 459 M
-( These have the following meanings:) s
-5 437 M
-( SSH_FXF_READ) s
-5 426 M
-( Open the file for reading.) s
-5 404 M
-( SSH_FXF_WRITE) s
-5 393 M
-( Open the file for writing. If both this and SSH_FXF_READ are) s
-5 382 M
-( specified, the file is opened for both reading and writing.) s
-5 360 M
-( SSH_FXF_APPEND) s
-5 349 M
-( Force all writes to append data at the end of the file. The) s
-5 338 M
-( offset parameter to write will be ignored.) s
-5 316 M
-( SSH_FXF_CREAT) s
-5 305 M
-( If this flag is specified, then a new file will be created if one) s
-5 294 M
-( does not already exist \(if O_TRUNC is specified, the new file will) s
-5 283 M
-( be truncated to zero length if it previously exists\).) s
-5 261 M
-( SSH_FXF_TRUNC) s
-5 250 M
-( Forces an existing file with the same name to be truncated to zero) s
-5 239 M
-( length when creating a file by specifying SSH_FXF_CREAT.) s
-5 228 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 206 M
-( SSH_FXF_EXCL) s
-5 195 M
-( Causes the request to fail if the named file already exists.) s
-5 184 M
-( SSH_FXF_CREAT MUST also be specified if this flag is used.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXF_TEXT) s
-5 679 M
-( Indicates that the server should treat the file as text and) s
-5 668 M
-( convert it to the canonical newline convention in use. \(See) s
-5 657 M
-( Determining Server Newline Convention. \(Section 4.3\)) s
-5 635 M
-( When a file is opened with the FXF_TEXT flag, the offset field in) s
-5 624 M
-( both the read and write function are ignored.) s
-5 602 M
-( Servers MUST correctly process multiple parallel reads and writes) s
-5 591 M
-( correctly in this mode. Naturally, it is permissible for them to) s
-5 580 M
-( do this by serializing the requests. It would not be possible for) s
-5 569 M
-( a client to reliably detect a server that does not implement) s
-5 558 M
-( parallel writes in time to prevent damage.) s
-5 536 M
-( Clients SHOULD use the SSH_FXF_APPEND flag to append data to a) s
-5 525 M
-( text file rather then using write with a calculated offset.) s
-5 503 M
-( To support seeks on text file the following SSH_FXP_EXTENDED) s
-5 492 M
-( packet is defined.) s
-5 448 M
-( string "text-seek") s
-5 437 M
-( string file-handle) s
-5 426 M
-( uint64 line-number) s
-5 404 M
-( line-number is the index of the line number to seek to, where byte) s
-5 393 M
-( 0 in the file is line number 0, and the byte directly following) s
-5 382 M
-( the first newline sequence in the file is line number 1 and so on.) s
-5 360 M
-( The response to a "text-seek" request is an SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( An attempt to seek past the end-of-file should result in a) s
-5 316 M
-( SSH_FX_EOF status.) s
-5 294 M
-( Servers SHOULD support at least one "text-seek" in order to) s
-5 283 M
-( support resume. However, a client MUST be prepared to receive) s
-5 272 M
-( SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.) s
-5 261 M
-( The client can then try a fall-back strategy, if it has one.) s
-5 239 M
-( Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned) s
-5 228 M
-( for read or write operations that are not sequential.) s
-5 206 M
-( The `attrs' field specifies the initial attributes for the file.) s
-5 195 M
-( Default values will be used for those attributes that are not) s
-5 184 M
-( specified. See Section ``File Attributes'' for more information.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( The response to this message will be either SSH_FXP_HANDLE \(if the) s
-5 679 M
-( operation is successful\) or SSH_FXP_STATUS \(if the operation fails\).) s
-5 657 M
-( A file is closed by using the SSH_FXP_CLOSE request. Its data field) s
-5 646 M
-( has the following format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string handle) s
-5 591 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 580 M
-( previously returned in the response to SSH_FXP_OPEN or) s
-5 569 M
-( SSH_FXP_OPENDIR. The handle becomes invalid immediately after this) s
-5 558 M
-( request has been sent.) s
-5 536 M
-( The response to this request will be a SSH_FXP_STATUS message. One) s
-5 525 M
-( should note that on some server platforms even a close can fail.) s
-5 514 M
-( This can happen e.g. if the server operating system caches writes,) s
-5 503 M
-( and an error occurs while flushing cached writes during the close.) s
-5 481 M
-(6.4 Reading and Writing) s
-5 459 M
-( Once a file has been opened, it can be read using the SSH_FXP_READ) s
-5 448 M
-( message, which has the following format:) s
-5 426 M
-( uint32 id) s
-5 415 M
-( string handle) s
-5 404 M
-( uint64 offset) s
-5 393 M
-( uint32 len) s
-5 371 M
-( where `id' is the request identifier, `handle' is an open file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) relative) s
-5 349 M
-( to the beginning of the file from where to start reading, and `len') s
-5 338 M
-( is the maximum number of bytes to read.) s
-5 316 M
-( In response to this request, the server will read as many bytes as it) s
-5 305 M
-( can from the file \(up to `len'\), and return them in a SSH_FXP_DATA) s
-5 294 M
-( message. If an error occurs or EOF is encountered before reading any) s
-5 283 M
-( data, the server will respond with SSH_FXP_STATUS. For normal disk) s
-5 272 M
-( files, it is guaranteed that this will read the specified number of) s
-5 261 M
-( bytes, or up to end of file. For e.g. device files this may return) s
-5 250 M
-( fewer bytes than requested.) s
-5 228 M
-( Writing to a file is achieved using the SSH_FXP_WRITE message, which) s
-5 217 M
-( has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( string handle) s
-5 668 M
-( uint64 offset) s
-5 657 M
-( string data) s
-5 635 M
-( where `id' is a request identifier, `handle' is a file handle) s
-5 624 M
-( returned by SSH_FXP_OPEN, `offset' is the offset \(in bytes\) from the) s
-5 613 M
-( beginning of the file where to start writing, and `data' is the data) s
-5 602 M
-( to be written.) s
-5 580 M
-( The write will extend the file if writing beyond the end of the file.) s
-5 569 M
-( It is legal to write way beyond the end of the file; the semantics) s
-5 558 M
-( are to write zeroes from the end of the file to the specified offset) s
-5 547 M
-( and then the data. On most operating systems, such writes do not) s
-5 536 M
-( allocate disk space but instead leave "holes" in the file.) s
-5 514 M
-( The server responds to a write request with a SSH_FXP_STATUS message.) s
-5 492 M
-(6.5 Removing and Renaming Files) s
-5 470 M
-( Files can be removed using the SSH_FXP_REMOVE message. It has the) s
-5 459 M
-( following format:) s
-5 437 M
-( uint32 id) s
-5 426 M
-( string filename [UTF-8]) s
-5 404 M
-( where `id' is the request identifier and `filename' is the name of) s
-5 393 M
-( the file to be removed. See Section ``File Names'' for more) s
-5 382 M
-( information. This request cannot be used to remove directories.) s
-5 360 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 349 M
-( message.) s
-5 327 M
-( Files \(and directories\) can be renamed using the SSH_FXP_RENAME) s
-5 316 M
-( message. Its data is as follows:) s
-5 294 M
-( uint32 id) s
-5 283 M
-( string oldpath [UTF-8]) s
-5 272 M
-( string newpath [UTF-8]) s
-5 250 M
-( where `id' is the request identifier, `oldpath' is the name of an) s
-5 239 M
-( existing file or directory, and `newpath' is the new name for the) s
-5 228 M
-( file or directory. It is an error if there already exists a file) s
-5 217 M
-( with the name specified by newpath. The server may also fail rename) s
-5 206 M
-( requests in other situations, for example if `oldpath' and `newpath') s
-5 195 M
-( point to different file systems on the server.) s
-5 173 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( message.) s
-5 668 M
-(6.6 Creating and Deleting Directories) s
-5 646 M
-( New directories can be created using the SSH_FXP_MKDIR request. It) s
-5 635 M
-( has the following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 591 M
-( ATTRS attrs) s
-5 569 M
-( where `id' is the request identifier.) s
-5 547 M
-( `path' specifies the directory to be created. See Section ``File) s
-5 536 M
-( Names'' for more information on file names.) s
-5 514 M
-( `attrs' specifies the attributes that should be applied to it upon) s
-5 503 M
-( creation. Attributes are discussed in more detail in Section ``File) s
-5 492 M
-( Attributes''.) s
-5 470 M
-( The server will respond to this request with a SSH_FXP_STATUS) s
-5 459 M
-( message. If a file or directory with the specified path already) s
-5 448 M
-( exists, an error will be returned.) s
-5 426 M
-( Directories can be removed using the SSH_FXP_RMDIR request, which has) s
-5 415 M
-( the following format:) s
-5 393 M
-( uint32 id) s
-5 382 M
-( string path [UTF-8]) s
-5 360 M
-( where `id' is the request identifier, and `path' specifies the) s
-5 349 M
-( directory to be removed. See Section ``File Names'' for more) s
-5 338 M
-( information on file names.) s
-5 316 M
-( The server responds to this request with a SSH_FXP_STATUS message.) s
-5 305 M
-( Errors may be returned from this operation for various reasons,) s
-5 294 M
-( including, but not limited to, the path does not exist, the path does) s
-5 283 M
-( not refer to a directory object, the directory is not empty, or the) s
-5 272 M
-( user has insufficient access or permission to perform the requested) s
-5 261 M
-( operation.) s
-5 239 M
-(6.7 Scanning Directories) s
-5 217 M
-( The files in a directory can be listed using the SSH_FXP_OPENDIR and) s
-5 206 M
-( SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one) s
-5 195 M
-( or more file names with full file attributes for each file. The) s
-5 184 M
-( client should call SSH_FXP_READDIR repeatedly until it has found the) s
-5 173 M
-( file it is looking for or until the server responds with a) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FXP_STATUS message indicating an error \(normally SSH_FX_EOF if) s
-5 679 M
-( there are no more files in the directory\). The client should then) s
-5 668 M
-( close the handle using the SSH_FXP_CLOSE request.) s
-5 646 M
-( The SSH_FXP_OPENDIR opens a directory for reading. It has the) s
-5 635 M
-( following format:) s
-5 613 M
-( uint32 id) s
-5 602 M
-( string path [UTF-8]) s
-5 580 M
-( where `id' is the request identifier and `path' is the path name of) s
-5 569 M
-( the directory to be listed \(without any trailing slash\). See Section) s
-5 558 M
-( ``File Names'' for more information on file names. This will return) s
-5 547 M
-( an error if the path does not specify a directory or if the directory) s
-5 536 M
-( is not readable. The server will respond to this request with either) s
-5 525 M
-( a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.) s
-5 503 M
-( Once the directory has been successfully opened, files \(and) s
-5 492 M
-( directories\) contained in it can be listed using SSH_FXP_READDIR) s
-5 481 M
-( requests. These are of the format) s
-5 459 M
-( uint32 id) s
-5 448 M
-( string handle) s
-5 426 M
-( where `id' is the request identifier, and `handle' is a handle) s
-5 415 M
-( returned by SSH_FXP_OPENDIR. \(It is a protocol error to attempt to) s
-5 404 M
-( use an ordinary file handle returned by SSH_FXP_OPEN.\)) s
-5 382 M
-( The server responds to this request with either a SSH_FXP_NAME or a) s
-5 371 M
-( SSH_FXP_STATUS message. One or more names may be returned at a time.) s
-5 360 M
-( Full status information is returned for each name in order to speed) s
-5 349 M
-( up typical directory listings.) s
-5 327 M
-( If there are no more names available to be read, the server MUST) s
-5 316 M
-( respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.) s
-5 294 M
-( When the client no longer wishes to read more names from the) s
-5 283 M
-( directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle) s
-5 272 M
-( should be closed regardless of whether an error has occurred or not.) s
-5 250 M
-(6.8 Retrieving File Attributes) s
-5 228 M
-( Very often, file attributes are automatically returned by) s
-5 217 M
-( SSH_FXP_READDIR. However, sometimes there is need to specifically) s
-5 206 M
-( retrieve the attributes for a named file. This can be done using the) s
-5 195 M
-( SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.) s
-5 173 M
-( SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( follows symbolic links on the server, whereas SSH_FXP_LSTAT does not) s
-5 679 M
-( follow symbolic links. Both have the same format:) s
-5 657 M
-( uint32 id) s
-5 646 M
-( string path [UTF-8]) s
-5 635 M
-( uint32 flags) s
-5 613 M
-( where `id' is the request identifier, and `path' specifies the file) s
-5 602 M
-( system object for which status is to be returned. The server) s
-5 591 M
-( responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 569 M
-( The flags field specify the attribute flags in which the client has) s
-5 558 M
-( particular interest. This is a hint to the server. For example,) s
-5 547 M
-( because retrieving owner / group and acl information can be an) s
-5 536 M
-( expensive operation under some operating systems, the server may) s
-5 525 M
-( choose not to retrieve this information unless the client expresses a) s
-5 514 M
-( specific interest in it.) s
-5 492 M
-( The client has no guarantee the server will provide all the fields) s
-5 481 M
-( that it has expressed an interest in.) s
-5 459 M
-( SSH_FXP_FSTAT differs from the others in that it returns status) s
-5 448 M
-( information for an open file \(identified by the file handle\). Its) s
-5 437 M
-( format is as follows:) s
-5 415 M
-( uint32 id) s
-5 404 M
-( string handle) s
-5 393 M
-( uint32 flags) s
-5 371 M
-( where `id' is the request identifier and `handle' is a file handle) s
-5 360 M
-( returned by SSH_FXP_OPEN. The server responds to this request with) s
-5 349 M
-( SSH_FXP_ATTRS or SSH_FXP_STATUS.) s
-5 327 M
-(6.9 Setting File Attributes) s
-5 305 M
-( File attributes may be modified using the SSH_FXP_SETSTAT and) s
-5 294 M
-( SSH_FXP_FSETSTAT requests. These requests are used for operations) s
-5 283 M
-( such as changing the ownership, permissions or access times, as well) s
-5 272 M
-( as for truncating a file.) s
-5 250 M
-( The SSH_FXP_SETSTAT request is of the following format:) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string path [UTF-8]) s
-5 206 M
-( ATTRS attrs) s
-5 184 M
-( where `id' is the request identifier, `path' specifies the file) s
-5 173 M
-( system object \(e.g. file or directory\) whose attributes are to be) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 679 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 668 M
-( ``File Attributes''.) s
-5 646 M
-( An error will be returned if the specified file system object does) s
-5 635 M
-( not exist or the user does not have sufficient rights to modify the) s
-5 624 M
-( specified attributes. The server responds to this request with a) s
-5 613 M
-( SSH_FXP_STATUS message.) s
-5 591 M
-( The SSH_FXP_FSETSTAT request modifies the attributes of a file which) s
-5 580 M
-( is already open. It has the following format:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string handle) s
-5 536 M
-( ATTRS attrs) s
-5 514 M
-( where `id' is the request identifier, `handle' \(MUST be returned by) s
-5 503 M
-( SSH_FXP_OPEN\) identifies the file whose attributes are to be) s
-5 492 M
-( modified, and `attrs' specifies the modifications to be made to its) s
-5 481 M
-( attributes. Attributes are discussed in more detail in Section) s
-5 470 M
-( ``File Attributes''. The server will respond to this request with) s
-5 459 M
-( SSH_FXP_STATUS.) s
-5 437 M
-(6.10 Dealing with Symbolic links) s
-5 415 M
-( The SSH_FXP_READLINK request may be used to read the target of a) s
-5 404 M
-( symbolic link. It would have a data part as follows:) s
-5 382 M
-( uint32 id) s
-5 371 M
-( string path [UTF-8]) s
-5 349 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 338 M
-( name of the symlink to be read.) s
-5 316 M
-( The server will respond with a SSH_FXP_NAME packet containing only) s
-5 305 M
-( one name and a dummy attributes value. The name in the returned) s
-5 294 M
-( packet contains the target of the link. If an error occurs, the) s
-5 283 M
-( server may respond with SSH_FXP_STATUS.) s
-5 261 M
-( The SSH_FXP_SYMLINK request will create a symbolic link on the) s
-5 250 M
-( server. It is of the following format) s
-5 228 M
-( uint32 id) s
-5 217 M
-( string linkpath [UTF-8]) s
-5 206 M
-( string targetpath [UTF-8]) s
-5 184 M
-( where `id' is the request identifier, `linkpath' specifies the path) s
-5 173 M
-( name of the symlink to be created and `targetpath' specifies the) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( target of the symlink. The server shall respond with a) s
-5 679 M
-( SSH_FXP_STATUS indicating either success \(SSH_FX_OK\) or an error) s
-5 668 M
-( condition.) s
-5 646 M
-(6.11 Canonicalizing the Server-Side Path Name) s
-5 624 M
-( The SSH_FXP_REALPATH request can be used to have the server) s
-5 613 M
-( canonicalize any given path name to an absolute path. This is useful) s
-5 602 M
-( for converting path names containing ".." components or relative) s
-5 591 M
-( pathnames without a leading slash into absolute paths. The format of) s
-5 580 M
-( the request is as follows:) s
-5 558 M
-( uint32 id) s
-5 547 M
-( string path [UTF-8]) s
-5 525 M
-( where `id' is the request identifier and `path' specifies the path) s
-5 514 M
-( name to be canonicalized. The server will respond with a) s
-5 503 M
-( SSH_FXP_NAME packet containing the name in canonical form and a dummy) s
-5 492 M
-( attributes value. If an error occurs, the server may also respond) s
-5 481 M
-( with SSH_FXP_STATUS.) s
-5 459 M
-(6.11.1 Best practice for dealing with paths) s
-5 437 M
-( The client SHOULD treat the results of SSH_FXP_REALPATH as a) s
-5 426 M
-( canonical absolute path, even if the path does not appear to be) s
-5 415 M
-( absolute. A client that use REALPATH\("."\) and treats the result as) s
-5 404 M
-( absolute, even if there is no leading slash, will continue to) s
-5 393 M
-( function correctly, even when talking to a Windows NT or VMS style) s
-5 382 M
-( system, where absolute paths may not begin with a slash.) s
-5 360 M
-( For example, if the client wishes to change directory up, and the) s
-5 349 M
-( server has returned "c:/x/y/z" from REALPATH, the client SHOULD use) s
-5 338 M
-( "c:/x/y/z/..".) s
-5 316 M
-( As a second example, if the client wishes to open the file "x.txt" in) s
-5 305 M
-( the current directory, and server has returned "dka100:/x/y/z" as the) s
-5 294 M
-( canonical path of the directory, the client SHOULD open "dka100:/x/y/) s
-5 283 M
-( z/x.txt") s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(7. Responses from the Server to the Client) s
-5 668 M
-( The server responds to the client using one of a few response) s
-5 657 M
-( packets. All requests can return a SSH_FXP_STATUS response upon) s
-5 646 M
-( failure. When the operation is successful, any of the responses may) s
-5 635 M
-( be returned \(depending on the operation\). If no data needs to be) s
-5 624 M
-( returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK) s
-5 613 M
-( status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used) s
-5 602 M
-( to return a file handle \(for SSH_FXP_OPEN and SSH_FXP_OPENDIR) s
-5 591 M
-( requests\), SSH_FXP_DATA is used to return data from SSH_FXP_READ,) s
-5 580 M
-( SSH_FXP_NAME is used to return one or more file names from a) s
-5 569 M
-( SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is) s
-5 558 M
-( used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and) s
-5 547 M
-( SSH_FXP_FSTAT requests.) s
-5 525 M
-( Exactly one response will be returned for each request. Each) s
-5 514 M
-( response packet contains a request identifier which can be used to) s
-5 503 M
-( match each response with the corresponding request. Note that it is) s
-5 492 M
-( legal to have several requests outstanding simultaneously, and the) s
-5 481 M
-( server is allowed to send responses to them in a different order from) s
-5 470 M
-( the order in which the requests were sent \(the result of their) s
-5 459 M
-( execution, however, is guaranteed to be as if they had been processed) s
-5 448 M
-( one at a time in the order in which the requests were sent\).) s
-5 426 M
-( Response packets are of the same general format as request packets.) s
-5 415 M
-( Each response packet begins with the request identifier.) s
-5 393 M
-( The format of the data portion of the SSH_FXP_STATUS response is as) s
-5 382 M
-( follows:) s
-5 360 M
-( uint32 id) s
-5 349 M
-( uint32 error/status code) s
-5 338 M
-( string error message \(ISO-10646 UTF-8 [RFC-2279]\)) s
-5 327 M
-( string language tag \(as defined in [RFC-1766]\)) s
-5 305 M
-( where `id' is the request identifier, and `error/status code') s
-5 294 M
-( indicates the result of the requested operation. The value SSH_FX_OK) s
-5 283 M
-( indicates success, and all other values indicate failure.) s
-5 261 M
-( Currently, the following values are defined \(other values may be) s
-5 250 M
-( defined by future versions of this protocol\):) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( #define SSH_FX_OK 0) s
-5 679 M
-( #define SSH_FX_EOF 1) s
-5 668 M
-( #define SSH_FX_NO_SUCH_FILE 2) s
-5 657 M
-( #define SSH_FX_PERMISSION_DENIED 3) s
-5 646 M
-( #define SSH_FX_FAILURE 4) s
-5 635 M
-( #define SSH_FX_BAD_MESSAGE 5) s
-5 624 M
-( #define SSH_FX_NO_CONNECTION 6) s
-5 613 M
-( #define SSH_FX_CONNECTION_LOST 7) s
-5 602 M
-( #define SSH_FX_OP_UNSUPPORTED 8) s
-5 591 M
-( #define SSH_FX_INVALID_HANDLE 9) s
-5 580 M
-( #define SSH_FX_NO_SUCH_PATH 10) s
-5 569 M
-( #define SSH_FX_FILE_ALREADY_EXISTS 11) s
-5 558 M
-( #define SSH_FX_WRITE_PROTECT 12) s
-5 536 M
-( SSH_FX_OK) s
-5 525 M
-( Indicates successful completion of the operation.) s
-5 503 M
-( SSH_FX_EOF) s
-5 492 M
-( indicates end-of-file condition; for SSH_FX_READ it means that no) s
-5 481 M
-( more data is available in the file, and for SSH_FX_READDIR it) s
-5 470 M
-( indicates that no more files are contained in the directory.) s
-5 448 M
-( SSH_FX_NO_SUCH_FILE) s
-5 437 M
-( is returned when a reference is made to a file which does not) s
-5 426 M
-( exist.) s
-5 404 M
-( SSH_FX_PERMISSION_DENIED) s
-5 393 M
-( is returned when the authenticated user does not have sufficient) s
-5 382 M
-( permissions to perform the operation.) s
-5 360 M
-( SSH_FX_FAILURE) s
-5 349 M
-( is a generic catch-all error message; it should be returned if an) s
-5 338 M
-( error occurs for which there is no more specific error code) s
-5 327 M
-( defined.) s
-5 305 M
-( SSH_FX_BAD_MESSAGE) s
-5 294 M
-( may be returned if a badly formatted packet or protocol) s
-5 283 M
-( incompatibility is detected.) s
-5 261 M
-( SSH_FX_NO_CONNECTION) s
-5 250 M
-( is a pseudo-error which indicates that the client has no) s
-5 239 M
-( connection to the server \(it can only be generated locally by the) s
-5 228 M
-( client, and MUST NOT be returned by servers\).) s
-5 206 M
-( SSH_FX_CONNECTION_LOST) s
-5 195 M
-( is a pseudo-error which indicates that the connection to the) s
-5 184 M
-( server has been lost \(it can only be generated locally by the) s
-5 173 M
-( client, and MUST NOT be returned by servers\).) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( SSH_FX_OP_UNSUPPORTED) s
-5 679 M
-( indicates that an attempt was made to perform an operation which) s
-5 668 M
-( is not supported for the server \(it may be generated locally by) s
-5 657 M
-( the client if e.g. the version number exchange indicates that a) s
-5 646 M
-( required feature is not supported by the server, or it may be) s
-5 635 M
-( returned by the server if the server does not implement an) s
-5 624 M
-( operation\).) s
-5 602 M
-( SSH_FX_INVALID_HANDLE) s
-5 591 M
-( The handle value was invalid.) s
-5 569 M
-( SSH_FX_NO_SUCH_PATH) s
-5 558 M
-( The file path does not exist or is invalid.) s
-5 536 M
-( SSH_FX_FILE_ALREADY_EXISTS) s
-5 525 M
-( The file already exists.) s
-5 503 M
-( SSH_FX_WRITE_PROTECT) s
-5 492 M
-( The file is on read only media, or the media is write protected.) s
-5 470 M
-( The SSH_FXP_HANDLE response has the following format:) s
-5 448 M
-( uint32 id) s
-5 437 M
-( string handle) s
-5 415 M
-( where `id' is the request identifier, and `handle' is an arbitrary) s
-5 404 M
-( string that identifies an open file or directory on the server. The) s
-5 393 M
-( handle is opaque to the client; the client MUST NOT attempt to) s
-5 382 M
-( interpret or modify it in any way. The length of the handle string) s
-5 371 M
-( MUST NOT exceed 256 data bytes.) s
-5 349 M
-( The SSH_FXP_DATA response has the following format:) s
-5 327 M
-( uint32 id) s
-5 316 M
-( string data) s
-5 294 M
-( where `id' is the request identifier, and `data' is an arbitrary byte) s
-5 283 M
-( string containing the requested data. The data string may be at most) s
-5 272 M
-( the number of bytes requested in a SSH_FXP_READ request, but may also) s
-5 261 M
-( be shorter if end of file is reached or if the read is from something) s
-5 250 M
-( other than a regular file.) s
-5 228 M
-( The SSH_FXP_NAME response has the following format:) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( uint32 id) s
-5 679 M
-( uint32 count) s
-5 668 M
-( repeats count times:) s
-5 657 M
-( string filename [UTF-8]) s
-5 646 M
-( ATTRS attrs) s
-5 624 M
-( where `id' is the request identifier, `count' is the number of names) s
-5 613 M
-( returned in this response, and the remaining fields repeat `count') s
-5 602 M
-( times \(so that all three fields are first included for the first) s
-5 591 M
-( file, then for the second file, etc\). In the repeated part,) s
-5 580 M
-( `filename' is a file name being returned \(for SSH_FXP_READDIR, it) s
-5 569 M
-( will be a relative name within the directory, without any path) s
-5 558 M
-( components; for SSH_FXP_REALPATH it will be an absolute path name\),) s
-5 547 M
-( and `attrs' is the attributes of the file as described in Section) s
-5 536 M
-( ``File Attributes''.) s
-5 514 M
-( The SSH_FXP_ATTRS response has the following format:) s
-5 492 M
-( uint32 id) s
-5 481 M
-( ATTRS attrs) s
-5 459 M
-( where `id' is the request identifier, and `attrs' is the returned) s
-5 448 M
-( file attributes as described in Section ``File Attributes''.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(8. Vendor-Specific Extensions) s
-5 668 M
-( The SSH_FXP_EXTENDED request provides a generic extension mechanism) s
-5 657 M
-( for adding vendor-specific commands. The request has the following) s
-5 646 M
-( format:) s
-5 624 M
-( uint32 id) s
-5 613 M
-( string extended-request) s
-5 602 M
-( ... any request-specific data ...) s
-5 580 M
-( where `id' is the request identifier, and `extended-request' is a) s
-5 569 M
-( string of the format "name@domain", where domain is an internet) s
-5 558 M
-( domain name of the vendor defining the request. The rest of the) s
-5 547 M
-( request is completely vendor-specific, and servers should only) s
-5 536 M
-( attempt to interpret it if they recognize the `extended-request') s
-5 525 M
-( name.) s
-5 503 M
-( The server may respond to such requests using any of the response) s
-5 492 M
-( packets defined in Section ``Responses from the Server to the) s
-5 481 M
-( Client''. Additionally, the server may also respond with a) s
-5 470 M
-( SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does) s
-5 459 M
-( not recognize the `extended-request' name, then the server MUST) s
-5 448 M
-( respond with SSH_FXP_STATUS with error/status set to) s
-5 437 M
-( SSH_FX_OP_UNSUPPORTED.) s
-5 415 M
-( The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary) s
-5 404 M
-( extension-specific data from the server to the client. It is of the) s
-5 393 M
-( following format:) s
-5 371 M
-( uint32 id) s
-5 360 M
-( ... any request-specific data ...) s
-5 338 M
-( There is a range of packet types reserved for use by extensions. In) s
-5 327 M
-( order to avoid collision, extensions that turn on the use of) s
-5 316 M
-( additional packet types should determine those numbers dynamically.) s
-5 294 M
-( The suggested way of doing this is have an extension request from the) s
-5 283 M
-( client to the server that enables the extension; the extension) s
-5 272 M
-( response from the server to the client would specify the actual type) s
-5 261 M
-( values to use, in additional to any other data.) s
-5 239 M
-( Extension authors should be mindful of the limited range of packet) s
-5 228 M
-( types available \(there are only 45 values available\) and avoid) s
-5 217 M
-( requiring a new packet type where possible.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(9. Security Considerations) s
-5 668 M
-( This protocol assumes that it is run over a secure channel and that) s
-5 657 M
-( the endpoints of the channel have been authenticated. Thus, this) s
-5 646 M
-( protocol assumes that it is externally protected from network-level) s
-5 635 M
-( attacks.) s
-5 613 M
-( This protocol provides file system access to arbitrary files on the) s
-5 602 M
-( server \(only constrained by the server implementation\). It is the) s
-5 591 M
-( responsibility of the server implementation to enforce any access) s
-5 580 M
-( controls that may be required to limit the access allowed for any) s
-5 569 M
-( particular user \(the user being authenticated externally to this) s
-5 558 M
-( protocol, typically using the SSH User Authentication Protocol [8].) s
-5 536 M
-( Care must be taken in the server implementation to check the validity) s
-5 525 M
-( of received file handle strings. The server should not rely on them) s
-5 514 M
-( directly; it MUST check the validity of each handle before relying on) s
-5 503 M
-( it.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 30 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10. Changes from previous protocol versions) s
-5 668 M
-( The SSH File Transfer Protocol has changed over time, before it's) s
-5 657 M
-( standardization. The following is a description of the incompatible) s
-5 646 M
-( changes between different versions.) s
-5 624 M
-(10.1 Changes between versions 4 and 3) s
-5 602 M
-( Many of the changes between version 4 and version 3 are to the) s
-5 591 M
-( attribute structure to make it more flexible for non-unix platforms.) s
-5 569 M
-( o Make all filenames UTF-8.) s
-5 547 M
-( o Added 'newline' extension.) s
-5 525 M
-( o Made file attribute owner and group strings so they can actually) s
-5 514 M
-( be used on disparate systems.) s
-5 492 M
-( o Added createtime field, and added separate flags for atime,) s
-5 481 M
-( createtime, and mtime so they can be set separately.) s
-5 459 M
-( o Split the file type out of the permissions field and into it's own) s
-5 448 M
-( field \(which is always present.\)) s
-5 426 M
-( o Added acl attribute.) s
-5 404 M
-( o Added SSH_FXF_TEXT file open flag.) s
-5 382 M
-( o Added flags field to the get stat commands so that the client can) s
-5 371 M
-( specifically request information the server might not normally) s
-5 360 M
-( included for performance reasons.) s
-5 338 M
-( o Removed the long filename from the names structure-- it can now be) s
-5 327 M
-( built from information available in the attrs structure.) s
-5 305 M
-( o Added reserved range of packet numbers for extensions.) s
-5 283 M
-( o Added several additional error codes.) s
-5 261 M
-( o Change the way version negotiate works slightly. Previously, if) s
-5 250 M
-( the client version were higher than the server version, the server) s
-5 239 M
-( was supposed to 'echo back' the clients version. The server now) s
-5 228 M
-( sends it's own version and the lower of the two is considered to) s
-5 217 M
-( be the one in use.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 30]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (30,31) 16
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 31 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(10.2 Changes between versions 3 and 2) s
-5 668 M
-( o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.) s
-5 646 M
-( o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were) s
-5 635 M
-( added.) s
-5 613 M
-( o The SSH_FXP_STATUS message was changed to include fields `error) s
-5 602 M
-( message' and `language tag'.) s
-5 569 M
-(10.3 Changes between versions 2 and 1) s
-5 547 M
-( o The SSH_FXP_RENAME message was added.) s
-5 514 M
-(10.4 Changes between versions 1 and 0) s
-5 492 M
-( o Implementation changes, no actual protocol changes.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 31]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 32 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(11. Trademark Issues) s
-5 668 M
-( "ssh" is a registered trademark of SSH Communications Security Corp) s
-5 657 M
-( in the United States and/or other countries.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 32]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (32,33) 17
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 33 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(References) s
-5 668 M
-( [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and) s
-5 657 M
-( P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January) s
-5 646 M
-( 1999.) s
-5 624 M
-( [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",) s
-5 613 M
-( BCP 18, RFC 2277, January 1998.) s
-5 591 M
-( [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,) s
-5 580 M
-( C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC) s
-5 569 M
-( 3010, December 2000.) s
-5 547 M
-( [4] Institute of Electrical and Electronics Engineers, "Information) s
-5 536 M
-( Technology - Portable Operating System Interface \(POSIX\) - Part) s
-5 525 M
-( 1: System Application Program Interface \(API\) [C Language]",) s
-5 514 M
-( IEEE Standard 1003.2, 1996.) s
-5 492 M
-( [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 481 M
-( Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-) s
-5 470 M
-( architecture-13 \(work in progress\), September 2002.) s
-5 448 M
-( [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 437 M
-( Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-) s
-5 426 M
-( transport-15 \(work in progress\), September 2002.) s
-5 404 M
-( [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 393 M
-( Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16) s
-5 382 M
-( \(work in progress\), September 2002.) s
-5 360 M
-( [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.) s
-5 349 M
-( Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-) s
-5 338 M
-( userauth-16 \(work in progress\), September 2002.) s
-5 305 M
-(Authors' Addresses) s
-5 283 M
-( Joseph Galbraith) s
-5 272 M
-( VanDyke Software) s
-5 261 M
-( 4848 Tramway Ridge Blvd) s
-5 250 M
-( Suite 101) s
-5 239 M
-( Albuquerque, NM 87111) s
-5 228 M
-( US) s
-5 206 M
-( Phone: +1 505 332 5700) s
-5 195 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 33]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 34 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-( Tatu Ylonen) s
-5 679 M
-( SSH Communications Security Corp) s
-5 668 M
-( Fredrikinkatu 42) s
-5 657 M
-( HELSINKI FIN-00100) s
-5 646 M
-( Finland) s
-5 624 M
-( EMail: [email protected]) s
-5 591 M
-( Sami Lehtinen) s
-5 580 M
-( SSH Communications Security Corp) s
-5 569 M
-( Fredrikinkatu 42) s
-5 558 M
-( HELSINKI FIN-00100) s
-5 547 M
-( Finland) s
-5 525 M
-( EMail: [email protected]) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 34]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (34,35) 18
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 35 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH File Transfer Protocol October 2002) s
-5 690 M
-(Full Copyright Statement) s
-5 668 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 646 M
-( This document and translations of it may be copied and furnished to) s
-5 635 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 624 M
-( or assist in its implementation may be prepared, copied, published) s
-5 613 M
-( and distributed, in whole or in part, without restriction of any) s
-5 602 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 591 M
-( included on all such copies and derivative works. However, this) s
-5 580 M
-( document itself may not be modified in any way, such as by removing) s
-5 569 M
-( the copyright notice or references to the Internet Society or other) s
-5 558 M
-( Internet organizations, except as needed for the purpose of) s
-5 547 M
-( developing Internet standards in which case the procedures for) s
-5 536 M
-( copyrights defined in the Internet Standards process must be) s
-5 525 M
-( followed, or as required to translate it into languages other than) s
-5 514 M
-( English.) s
-5 492 M
-( The limited permissions granted above are perpetual and will not be) s
-5 481 M
-( revoked by the Internet Society or its successors or assigns.) s
-5 459 M
-( This document and the information contained herein is provided on an) s
-5 448 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 437 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 426 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 415 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 404 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 382 M
-(Acknowledgement) s
-5 360 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 349 M
-( Internet Society.) s
-5 129 M
-(Galbraith, et al. Expires April 16, 2003 [Page 35]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 36 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 36
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
deleted file mode 100644
index 83960ae976..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-03.txt
+++ /dev/null
@@ -1,1962 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: April 16, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- October 16, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-03.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as Internet-
- Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on April 16, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 7
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 7
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 7
- 4.3 Determining Server Newline Convention . . . . . . . . . . 8
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 9
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 10
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 12
- 6. Requests From the Client to the Server . . . . . . . . . . 13
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 13
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 14
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 14
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 17
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 18
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 19
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 19
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 20
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 21
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 22
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 23
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 23
- 7. Responses from the Server to the Client . . . . . . . . . 24
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 28
- 9. Security Considerations . . . . . . . . . . . . . . . . . 29
- 10. Changes from previous protocol versions . . . . . . . . . 30
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 30
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 31
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 31
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 31
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 32
- References . . . . . . . . . . . . . . . . . . . . . . . . 33
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 33
- Full Copyright Statement . . . . . . . . . . . . . . . . . 35
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SSH_FILEXFER_ATTR_SIZE
- string owner present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- string group present only if flag SSH_FILEXFER_ATTR_OWNERGROUP
- uint32 permissions present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
- uint32 atime present only if flag SSH_FILEXFER_ATTR_ACCESSTIME
- uint32 createtime present only if flag SSH_FILEXFER_ATTR_CREATETIME
- uint32 mtime present only if flag SSH_FILEXFER_ATTR_MODIFYTIME
- string acl present only if flag SSH_FILEXFER_ATTR_ACL
- uint32 extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the SSH_FXP_READ
- message, which has the following format:
-
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS. For normal disk
- files, it is guaranteed that this will read the specified number of
- bytes, or up to end of file. For e.g. device files this may return
- fewer bytes than requested.
-
- Writing to a file is achieved using the SSH_FXP_WRITE message, which
- has the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
- The SSH_FXP_NAME response has the following format:
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
- o Change the way version negotiate works slightly. Previously, if
- the client version were higher than the server version, the server
- was supposed to 'echo back' the clients version. The server now
- sends it's own version and the lower of the two is considered to
- be the one in use.
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture", draft-ietf-secsh-
- architecture-13 (work in progress), September 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol", draft-ietf-secsh-
- transport-15 (work in progress), September 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol", draft-ietf-secsh-
- userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol October 2002
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires April 16, 2003 [Page 35]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt b/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
deleted file mode 100644
index 9f51883cd2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-filexfer-04.txt
+++ /dev/null
@@ -1,2130 +0,0 @@
-
-
-
-Secure Shell Working Group J. Galbraith
-Internet-Draft VanDyke Software
-Expires: June 18, 2003 T. Ylonen
- S. Lehtinen
- SSH Communications Security Corp
- December 18, 2002
-
-
- SSH File Transfer Protocol
- draft-ietf-secsh-filexfer-04.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as
- Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on June 18, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- The SSH File Transfer Protocol provides secure file transfer
- functionality over any reliable data stream. It is the standard file
- transfer protocol for use with the SSH2 protocol. This document
- describes the file transfer protocol and its interface to the SSH2
- protocol suite.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 1]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Table of Contents
-
- 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Use with the SSH Connection Protocol . . . . . . . . . . . 4
- 3. General Packet Format . . . . . . . . . . . . . . . . . . 5
- 3.1 The use of stderr in the server . . . . . . . . . . . . . 6
- 4. Protocol Initialization . . . . . . . . . . . . . . . . . 8
- 4.1 Client Initialization . . . . . . . . . . . . . . . . . . 8
- 4.2 Server Initialization . . . . . . . . . . . . . . . . . . 8
- 4.3 Determining Server Newline Convention . . . . . . . . . . 9
- 5. File Attributes . . . . . . . . . . . . . . . . . . . . . 10
- 5.1 Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 10
- 5.2 Type . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.3 Size . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
- 5.4 Owner and Group . . . . . . . . . . . . . . . . . . . . . 11
- 5.5 Permissions . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.6 Times . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.7 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
- 5.8 Extended attributes . . . . . . . . . . . . . . . . . . . 14
- 6. Requests From the Client to the Server . . . . . . . . . . 15
- 6.1 Request Synchronization and Reordering . . . . . . . . . . 15
- 6.2 File Names . . . . . . . . . . . . . . . . . . . . . . . . 16
- 6.3 Opening, Creating, and Closing Files . . . . . . . . . . . 16
- 6.4 Reading and Writing . . . . . . . . . . . . . . . . . . . 19
- 6.5 Removing and Renaming Files . . . . . . . . . . . . . . . 20
- 6.6 Creating and Deleting Directories . . . . . . . . . . . . 21
- 6.7 Scanning Directories . . . . . . . . . . . . . . . . . . . 21
- 6.8 Retrieving File Attributes . . . . . . . . . . . . . . . . 22
- 6.9 Setting File Attributes . . . . . . . . . . . . . . . . . 23
- 6.10 Dealing with Symbolic links . . . . . . . . . . . . . . . 24
- 6.11 Canonicalizing the Server-Side Path Name . . . . . . . . . 25
- 6.11.1 Best practice for dealing with paths . . . . . . . . . . . 25
- 7. Responses from the Server to the Client . . . . . . . . . 26
- 8. Vendor-Specific Extensions . . . . . . . . . . . . . . . . 30
- 9. Security Considerations . . . . . . . . . . . . . . . . . 31
- 10. Changes from previous protocol versions . . . . . . . . . 32
- 10.1 Changes between versions 4 and 3 . . . . . . . . . . . . . 32
- 10.2 Changes between versions 3 and 2 . . . . . . . . . . . . . 33
- 10.3 Changes between versions 2 and 1 . . . . . . . . . . . . . 33
- 10.4 Changes between versions 1 and 0 . . . . . . . . . . . . . 33
- 11. Trademark Issues . . . . . . . . . . . . . . . . . . . . . 34
- References . . . . . . . . . . . . . . . . . . . . . . . . 35
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . 35
- Intellectual Property and Copyright Statements . . . . . . 37
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 2]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-1. Introduction
-
- This protocol provides secure file transfer (and more generally file
- system access) functionality over a reliable data stream, such as a
- channel in the SSH2 protocol [5].
-
- This protocol is designed so that it could be used to implement a
- secure remote file system service, as well as a secure file transfer
- service.
-
- This protocol assumes that it runs over a secure channel, and that
- the server has already authenticated the user at the client end, and
- that the identity of the client user is externally available to the
- server implementation.
-
- In general, this protocol follows a simple request-response model.
- Each request and response contains a sequence number and multiple
- requests may be pending simultaneously. There are a relatively large
- number of different request messages, but a small number of possible
- response messages. Each request has one or more response messages
- that may be returned in result (e.g., a read either returns data or
- reports error status).
-
- The packet format descriptions in this specification follow the
- notation presented in the secsh architecture draft. [5]
-
- Even though this protocol is described in the context of the SSH2
- protocol, this protocol is general and independent of the rest of the
- SSH2 protocol suite. It could be used in a number of different
- applications, such as secure file transfer over TLS RFC 2246 [1] and
- transfer of management information in VPN applications.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 3]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-2. Use with the SSH Connection Protocol
-
- When used with the SSH2 Protocol suite, this protocol is intended to
- be used from the SSH Connection Protocol [7] as a subsystem, as
- described in section ``Starting a Shell or a Command''. The
- subsystem name used with this protocol is "sftp".
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 4]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-3. General Packet Format
-
- All packets transmitted over the secure connection are of the
- following format:
-
- uint32 length
- byte type
- byte[length - 1] data payload
-
- That is, they are just data preceded by 32-bit length and 8-bit type
- fields. The `length' is the length of the data area, and does not
- include the `length' field itself. The format and interpretation of
- the data area depends on the packet type.
-
- All packet descriptions below only specify the packet type and the
- data that goes into the data field. Thus, they should be prefixed by
- the `length' and `type' fields.
-
- The maximum size of a packet is in practice determined by the client
- (the maximum size of read or write requests that it sends, plus a few
- bytes of packet overhead). All servers SHOULD support packets of at
- least 34000 bytes (where the packet size refers to the full length,
- including the header above). This should allow for reads and writes
- of at most 32768 bytes.
-
- There is no limit on the number of outstanding (non-acknowledged)
- requests that the client may send to the server. In practice this is
- limited by the buffering available on the data stream and the queuing
- performed by the server. If the server's queues are full, it should
- not read any more data from the stream, and flow control will prevent
- the client from sending more requests. Note, however, that while
- there is no restriction on the protocol level, the client's API may
- provide a limit in order to prevent infinite queuing of outgoing
- requests at the client.
-
- The following values are defined for packet types.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 5]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FXP_INIT 1
- #define SSH_FXP_VERSION 2
- #define SSH_FXP_OPEN 3
- #define SSH_FXP_CLOSE 4
- #define SSH_FXP_READ 5
- #define SSH_FXP_WRITE 6
- #define SSH_FXP_LSTAT 7
- #define SSH_FXP_FSTAT 8
- #define SSH_FXP_SETSTAT 9
- #define SSH_FXP_FSETSTAT 10
- #define SSH_FXP_OPENDIR 11
- #define SSH_FXP_READDIR 12
- #define SSH_FXP_REMOVE 13
- #define SSH_FXP_MKDIR 14
- #define SSH_FXP_RMDIR 15
- #define SSH_FXP_REALPATH 16
- #define SSH_FXP_STAT 17
- #define SSH_FXP_RENAME 18
- #define SSH_FXP_READLINK 19
- #define SSH_FXP_SYMLINK 20
-
- #define SSH_FXP_STATUS 101
- #define SSH_FXP_HANDLE 102
- #define SSH_FXP_DATA 103
- #define SSH_FXP_NAME 104
- #define SSH_FXP_ATTRS 105
-
- #define SSH_FXP_EXTENDED 200
- #define SSH_FXP_EXTENDED_REPLY 201
-
- RESERVED_FOR_EXTENSIONS 210-255
-
- Additional packet types should only be defined if the protocol
- version number (see Section ``Protocol Initialization'') is
- incremented, and their use MUST be negotiated using the version
- number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY
- packets can be used to implement vendor-specific extensions. See
- Section ``Vendor-Specific-Extensions'' for more details.
-
-3.1 The use of stderr in the server
-
- Packets are sent and received on stdout and stdin. Data sent on
- stderr by the server SHOULD be considered debug or supplemental error
- information, and MAY be displayed to the user.
-
- For example, during initialization, there is no client request
- active, so errors or warning information cannot be sent to the client
- as part of the SFTP protocol at this early stage. However, the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 6]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- errors or warnings MAY be sent as stderr text.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 7]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-4. Protocol Initialization
-
- When the file transfer protocol starts, the client first sends a
- SSH_FXP_INIT (including its version number) packet to the server.
- The server responds with a SSH_FXP_VERSION packet, supplying the
- lowest of its own and the client's version number. Both parties
- should from then on adhere to particular version of the protocol.
-
- The version number of the protocol specified in this document is 4.
- The version number should be incremented for each incompatible
- revision of this protocol.
-
-4.1 Client Initialization
-
- The SSH_FXP_INIT packet (from client to server) has the following
- data:
-
- uint32 version
-
- Version 3 of this protocol allowed clients to include extensions in
- the SSH_FXP_INIT packet; however, this can cause interoperability
- problems with version 1 and version 2 servers because the client must
- send this packet before knowing the servers version.
-
- In this version of the protocol, clients MUST use the
- SSH_FXP_EXTENDED packet to send extensions to the server after
- version exchange has completed. Clients MUST NOT include extensions
- in the version packet. This will prevent interoperability problems
- with older servers
-
-4.2 Server Initialization
-
- The SSH_FXP_VERSION packet (from server to client) has the following
- data:
-
- uint32 version
- <extension data>
-
- 'version' is the lower of the protocol version supported by the
- server and the version number received from the client.
-
- The extension data may be empty, or may be a sequence of
-
- string extension_name
- string extension_data
-
- pairs (both strings MUST always be present if one is, but the
- `extension_data' string may be of zero length). If present, these
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 8]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- strings indicate extensions to the baseline protocol. The
- `extension_name' field(s) identify the name of the extension. The
- name should be of the form "name@domain", where the domain is the DNS
- domain name of the organization defining the extension. Additional
- names that are not of this format may be defined later by the IETF.
- Implementations MUST silently ignore any extensions whose name they
- do not recognize.
-
-4.3 Determining Server Newline Convention
-
- In order to correctly process text files in a cross platform
- compatible way, the newline convention must be converted from that of
- the server to that of the client, or, during an upload, from that of
- the client to that of the server.
-
- Versions 3 and prior of this protocol made no provisions for
- processing text files. Many clients implemented some sort of
- conversion algorithm, but without either a 'canonical' on the wire
- format or knowledge of the servers newline convention, correct
- conversion was not always possible.
-
- Starting with Version 4, the SSH_FXF_TEXT file open flag (Section
- 6.3) makes it possible to request that the server translate a file to
- a 'canonical' on the wire format. This format uses \r\n as the line
- separator.
-
- Servers for systems using multiple newline characters (for example,
- Mac OS X or VMS) or systems using counted records, MUST translate to
- the canonical form.
-
- However, to ease the burden of implementation on servers that use a
- single, simple separator sequence, the following extension allows the
- canonical format to be changed.
-
- string "newline"
- string new-canonical-separator (usually "\r" or "\n" or "\r\n")
-
- All clients MUST support this extension.
-
- When processing text files, clients SHOULD NOT translate any
- character or sequence that is not an exact match of the servers
- newline separator.
-
- In particular, if the newline sequence being used is the canonical
- "\r\n" sequence, a lone \r or a lone \n SHOULD be written through
- without change.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 9]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-5. File Attributes
-
- A new compound data type is defined for encoding file attributes.
- The same encoding is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- uint32 flags
- byte type always present
- uint64 size present only if flag SIZE
- string owner present only if flag OWNERGROUP
- string group present only if flag OWNERGROUP
- uint32 permissions present only if flag PERMISSIONS
- uint64 atime present only if flag ACCESSTIME
- uint32 atime_nseconds present only if flag SUBSECOND_TIMES
- uint64 createtime present only if flag CREATETIME
- uint32 createtime_nseconds present only if flag SUBSECOND_TIMES
- uint64 mtime present only if flag MODIFYTIME
- uint32 mtime_nseconds present only if flag SUBSECOND_TIMES
- string acl present only if flag ACL
- uint32 extended_count present only if flag EXTENDED
- string extended_type
- string extended_data
- ... more extended data (extended_type - extended_data pairs),
- so that number of pairs equals extended_count
-
-
-5.1 Flags
-
- The `flags' specify which of the fields are present. Those fields
- for which the corresponding flag is not set are not present (not
- included in the packet). New flags can only be added by incrementing
- the protocol version number (or by using the extension mechanism
- described below).
-
- The flags bits are defined to have the following values:
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 10]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FILEXFER_ATTR_SIZE 0x00000001
- #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000040
- #define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
- #define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
- #define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
- #define SSH_FILEXFER_ATTR_ACL 0x00000040
- #define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
- #define SSH_FILEXFER_ATTR_SUBSECOND_TIMES 0x00000100
- #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
-
- In previous versions of this protocol flags value 0x00000002 was
- SSH_FILEXFER_ATTR_UIDGID. This value is now unused, and OWNERGROUP
- was given a new value in order to ease implementation burden.
- 0x00000002 MUST NOT appear in the mask. Some future version of this
- protocol may reuse flag 0x00000002.
-
-5.2 Type
-
- The type field is always present. The following types are defined:
-
- #define SSH_FILEXFER_TYPE_REGULAR 1
- #define SSH_FILEXFER_TYPE_DIRECTORY 2
- #define SSH_FILEXFER_TYPE_SYMLINK 3
- #define SSH_FILEXFER_TYPE_SPECIAL 4
- #define SSH_FILEXFER_TYPE_UNKNOWN 5
-
- On a POSIX system, these values would be derived from the permission
- field.
-
-5.3 Size
-
- The `size' field specifies the size of the file on disk, in bytes.
- If it is present during file creation, it should be considered a hint
- as to the files eventual size.
-
- Files opened with the SSH_FXF_TEXT flag may have a size that is
- greater or less than the value of the size field.
-
-5.4 Owner and Group
-
- The `owner' and `group' fields are represented as UTF-8 strings; this
- is the form used by NFS v4. See NFS version 4 Protocol. [3] The
- following text is selected quotations from section 5.6.
-
- To avoid a representation that is tied to a particular underlying
- implementation at the client or server, the use of UTF-8 strings has
- been chosen. The string should be of the form user@dns_domain".
- This will allow for a client and server that do not use the same
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 11]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- local representation the ability to translate to a common syntax that
- can be interpreted by both. In the case where there is no
- translation available to the client or server, the attribute value
- must be constructed without the "@". Therefore, the absence of the @
- from the owner or owner_group attribute signifies that no translation
- was available and the receiver of the attribute should not place any
- special meaning with the attribute value. Even though the attribute
- value can not be translated, it may still be useful. In the case of
- a client, the attribute string may be used for local display of
- ownership.
-
-5.5 Permissions
-
- The `permissions' field contains a bit mask of file permissions as
- defined by POSIX [1].
-
-5.6 Times
-
- The 'atime', 'createtime', and 'mtime' contain the access, creation,
- and modification times of the files, respectively. They are
- represented as seconds from Jan 1, 1970 in UTC.
-
- A negative value indicates number of seconds before Jan 1, 1970. In
- both cases, if the SSH_FILEXFER_ATTR_SUBSECOND_TIMES flag is set, the
- nseconds field is to be added to the seconds field for the final time
- representation. For example, if the time to be represented is
- one-half second before 0 hour January 1, 1970, the seconds field
- would have a value of negative one (-1) and the nseconds fields would
- have a value of one-half second (500000000). Values greater than
- 999,999,999 for nseconds are considered invalid.
-
-5.7 ACL
-
- The 'ACL' field contains an ACL similar to that defined in section
- 5.9 of NFS version 4 Protocol [3].
-
- uint32 ace-count
-
- repeated ace-count time:
- uint32 ace-type
- uint32 ace-flag
- uint32 ace-mask
- string who [UTF-8]
-
- ace-type is one of the following four values (taken from NFS Version
- 4 Protocol [3]:
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 12]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000;
- const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001;
- const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002;
- const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003;
-
- ace-flag is a combination of the following flag values. See NFS
- Version 4 Protocol [3] section 5.9.2:
-
- const ACE4_FILE_INHERIT_ACE = 0x00000001;
- const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002;
- const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004;
- const ACE4_INHERIT_ONLY_ACE = 0x00000008;
- const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010;
- const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020;
- const ACE4_IDENTIFIER_GROUP = 0x00000040;
-
- ace-mask is any combination of the following flags (taken from NFS
- Version 4 Protocol [3] section 5.9.3:
-
- const ACE4_READ_DATA = 0x00000001;
- const ACE4_LIST_DIRECTORY = 0x00000001;
- const ACE4_WRITE_DATA = 0x00000002;
- const ACE4_ADD_FILE = 0x00000002;
- const ACE4_APPEND_DATA = 0x00000004;
- const ACE4_ADD_SUBDIRECTORY = 0x00000004;
- const ACE4_READ_NAMED_ATTRS = 0x00000008;
- const ACE4_WRITE_NAMED_ATTRS = 0x00000010;
- const ACE4_EXECUTE = 0x00000020;
- const ACE4_DELETE_CHILD = 0x00000040;
- const ACE4_READ_ATTRIBUTES = 0x00000080;
- const ACE4_WRITE_ATTRIBUTES = 0x00000100;
- const ACE4_DELETE = 0x00010000;
- const ACE4_READ_ACL = 0x00020000;
- const ACE4_WRITE_ACL = 0x00040000;
- const ACE4_WRITE_OWNER = 0x00080000;
- const ACE4_SYNCHRONIZE = 0x00100000;
-
- who is a UTF-8 string of the form described in 'Owner and Group'
- (Section 5.4)
-
- Also, as per '5.9.4 ACE who' [3] there are several identifiers that
- need to be understood universally. Some of these identifiers cannot
- be understood when an client access the server, but have meaning when
- a local process accesses the file. The ability to display and modify
- these permissions is permitted over SFTP.
-
- OWNER The owner of the file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 13]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- GROUP The group associated with the file.
-
- EVERYONE The world.
-
- INTERACTIVE Accessed from an interactive terminal.
-
- NETWORK Accessed via the network.
-
- DIALUP Accessed as a dialup user to the server.
-
- BATCH Accessed from a batch job.
-
- ANONYMOUS Accessed without any authentication.
-
- AUTHENTICATED Any authenticated user (opposite of ANONYMOUS).
-
- SERVICE Access from a system service.
-
- To avoid conflict, these special identifiers are distinguish by an
- appended "@" and should appear in the form "xxxx@" (note: no domain
- name after the "@"). For example: ANONYMOUS@.
-
-5.8 Extended attributes
-
- The SSH_FILEXFER_ATTR_EXTENDED flag provides a general extension
- mechanism for vendor-specific extensions. If the flag is specified,
- then the `extended_count' field is present. It specifies the number
- of extended_type-extended_data pairs that follow. Each of these
- pairs specifies an extended attribute. For each of the attributes,
- the extended_type field should be a string of the format
- "name@domain", where "domain" is a valid, registered domain name and
- "name" identifies the method. The IETF may later standardize certain
- names that deviate from this format (e.g., that do not contain the
- "@" sign). The interpretation of `extended_data' depends on the
- type. Implementations SHOULD ignore extended data fields that they
- do not understand.
-
- Additional fields can be added to the attributes by either defining
- additional bits to the flags field to indicate their presence, or by
- defining extended attributes for them. The extended attributes
- mechanism is recommended for most purposes; additional flags bits
- should only be defined by an IETF standards action that also
- increments the protocol version number. The use of such new fields
- MUST be negotiated by the version number in the protocol exchange.
- It is a protocol error if a packet with unsupported protocol bits is
- received.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 14]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6. Requests From the Client to the Server
-
- Requests from the client to the server represent the various file
- system operations. Each request begins with an `id' field, which is
- a 32-bit identifier identifying the request (selected by the client).
- The same identifier will be returned in the response to the request.
- One possible implementation is a monotonically increasing request
- sequence number (modulo 2^32).
-
- Many operations in the protocol operate on open files. The
- SSH_FXP_OPEN request can return a file handle (which is an opaque
- variable-length string) which may be used to access the file later
- (e.g. in a read operation). The client MUST NOT send requests the
- server with bogus or closed handles. However, the server MUST
- perform adequate checks on the handle in order to avoid security
- risks due to fabricated handles.
-
- This design allows either stateful and stateless server
- implementation, as well as an implementation which caches state
- between requests but may also flush it. The contents of the file
- handle string are entirely up to the server and its design. The
- client should not modify or attempt to interpret the file handle
- strings.
-
- The file handle strings MUST NOT be longer than 256 bytes.
-
-6.1 Request Synchronization and Reordering
-
- The protocol and implementations MUST process requests relating to
- the same file in the order in which they are received. In other
- words, if an application submits multiple requests to the server, the
- results in the responses will be the same as if it had sent the
- requests one at a time and waited for the response in each case. For
- example, the server may process non-overlapping read/write requests
- to the same file in parallel, but overlapping reads and writes cannot
- be reordered or parallelized. However, there are no ordering
- restrictions on the server for processing requests from two different
- file transfer connections. The server may interleave and parallelize
- them at will.
-
- There are no restrictions on the order in which responses to
- outstanding requests are delivered to the client, except that the
- server must ensure fairness in the sense that processing of no
- request will be indefinitely delayed even if the client is sending
- other requests so that there are multiple outstanding requests all
- the time.
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 15]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-6.2 File Names
-
- This protocol represents file names as strings. File names are
- assumed to use the slash ('/') character as a directory separator.
-
- File names starting with a slash are "absolute", and are relative to
- the root of the file system. Names starting with any other character
- are relative to the user's default directory (home directory). Note
- that identifying the user is assumed to take place outside of this
- protocol.
-
- Servers SHOULD interpret a path name component ".." as referring to
- the parent directory, and "." as referring to the current directory.
- If the server implementation limits access to certain parts of the
- file system, it must be extra careful in parsing file names when
- enforcing such restrictions. There have been numerous reported
- security bugs where a ".." in a path name has allowed access outside
- the intended area.
-
- An empty path name is valid, and it refers to the user's default
- directory (usually the user's home directory).
-
- Otherwise, no syntax is defined for file names by this specification.
- Clients should not make any other assumptions; however, they can
- splice path name components returned by SSH_FXP_READDIR together
- using a slash ('/') as the separator, and that will work as expected.
-
- In order to comply with IETF Policy on Character Sets and Languages
- [2], all filenames are to be encoded in UTF-8. The shortest valid
- UTF-8 encoding of the UNICODE data MUST be used. The server is
- responsible for converting the UNICODE data to whatever canonical
- form it requires.
-
- For example, if the server requires that precomposed characters
- always be used, the server MUST NOT assume the filename as sent by
- the client has this attribute, but must do this normalization itself.
-
- It is understood that the lack of well-defined semantics for file
- names may cause interoperability problems between clients and servers
- using radically different operating systems. However, this approach
- is known to work acceptably with most systems, and alternative
- approaches that e.g. treat file names as sequences of structured
- components are quite complicated.
-
-6.3 Opening, Creating, and Closing Files
-
- Files are opened and created using the SSH_FXP_OPEN message, whose
- data part is as follows:
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 16]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string filename [UTF-8]
- uint32 pflags
- ATTRS attrs
-
- The `id' field is the request identifier as for all requests.
-
- The `filename' field specifies the file name. See Section ``File
- Names'' for more information.
-
- The `pflags' field is a bitmask. The following bits have been
- defined.
-
- #define SSH_FXF_READ 0x00000001
- #define SSH_FXF_WRITE 0x00000002
- #define SSH_FXF_APPEND 0x00000004
- #define SSH_FXF_CREAT 0x00000008
- #define SSH_FXF_TRUNC 0x00000010
- #define SSH_FXF_EXCL 0x00000020
- #define SSH_FXF_TEXT 0x00000040
-
- These have the following meanings:
-
- SSH_FXF_READ
- Open the file for reading.
-
- SSH_FXF_WRITE
- Open the file for writing. If both this and SSH_FXF_READ are
- specified, the file is opened for both reading and writing.
-
- SSH_FXF_APPEND
- Force all writes to append data at the end of the file. The
- offset parameter to write will be ignored.
-
- SSH_FXF_CREAT
- If this flag is specified, then a new file will be created if one
- does not already exist (if O_TRUNC is specified, the new file will
- be truncated to zero length if it previously exists).
-
- SSH_FXF_TRUNC
- Forces an existing file with the same name to be truncated to zero
- length when creating a file by specifying SSH_FXF_CREAT.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
- SSH_FXF_EXCL
- Causes the request to fail if the named file already exists.
- SSH_FXF_CREAT MUST also be specified if this flag is used.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 17]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXF_TEXT
- Indicates that the server should treat the file as text and
- convert it to the canonical newline convention in use. (See
- Determining Server Newline Convention. (Section 4.3)
-
- When a file is opened with the FXF_TEXT flag, the offset field in
- both the read and write function are ignored.
-
- Servers MUST correctly process multiple parallel reads and writes
- correctly in this mode. Naturally, it is permissible for them to
- do this by serializing the requests. It would not be possible for
- a client to reliably detect a server that does not implement
- parallel writes in time to prevent damage.
-
- Clients SHOULD use the SSH_FXF_APPEND flag to append data to a
- text file rather then using write with a calculated offset.
-
- To support seeks on text file the following SSH_FXP_EXTENDED
- packet is defined.
-
-
-
- string "text-seek"
- string file-handle
- uint64 line-number
-
- line-number is the index of the line number to seek to, where byte
- 0 in the file is line number 0, and the byte directly following
- the first newline sequence in the file is line number 1 and so on.
-
- The response to a "text-seek" request is an SSH_FXP_STATUS
- message.
-
- An attempt to seek past the end-of-file should result in a
- SSH_FX_EOF status.
-
- Servers SHOULD support at least one "text-seek" in order to
- support resume. However, a client MUST be prepared to receive
- SSH_FX_OP_UNSUPPORTED when attempting a "text-seek" operation.
- The client can then try a fall-back strategy, if it has one.
-
- Clients MUST be prepared to handle SSH_FX_OP_UNSUPPORTED returned
- for read or write operations that are not sequential.
-
- The `attrs' field specifies the initial attributes for the file.
- Default values will be used for those attributes that are not
- specified. See Section ``File Attributes'' for more information.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 18]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The response to this message will be either SSH_FXP_HANDLE (if the
- operation is successful) or SSH_FXP_STATUS (if the operation fails).
-
- A file is closed by using the SSH_FXP_CLOSE request. Its data field
- has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- previously returned in the response to SSH_FXP_OPEN or
- SSH_FXP_OPENDIR. The handle becomes invalid immediately after this
- request has been sent.
-
- The response to this request will be a SSH_FXP_STATUS message. One
- should note that on some server platforms even a close can fail.
- This can happen e.g. if the server operating system caches writes,
- and an error occurs while flushing cached writes during the close.
-
-6.4 Reading and Writing
-
- Once a file has been opened, it can be read using the following
- message:
-
- byte SSH_FXP_READ
- uint32 id
- string handle
- uint64 offset
- uint32 len
-
- where `id' is the request identifier, `handle' is an open file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative
- to the beginning of the file from where to start reading, and `len'
- is the maximum number of bytes to read.
-
- In response to this request, the server will read as many bytes as it
- can from the file (up to `len'), and return them in a SSH_FXP_DATA
- message. If an error occurs or EOF is encountered before reading any
- data, the server will respond with SSH_FXP_STATUS.
-
- For normal disk files, it is normally guaranteed that this will read
- the specified number of bytes, or up to end of file. However, if the
- read length is very long, the server may truncate it if it doesn't
- support packets of that length. See General Packet Format (Section
- 3).
-
- For e.g. device files this may return fewer bytes than requested.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 19]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Writing to a file is achieved using the following message:
-
- byte SSH_FXP_WRITE
- uint32 id
- string handle
- uint64 offset
- string data
-
- where `id' is a request identifier, `handle' is a file handle
- returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) from the
- beginning of the file where to start writing, and `data' is the data
- to be written.
-
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file; the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data. On most operating systems, such writes do not
- allocate disk space but instead leave "holes" in the file.
-
- The server responds to a write request with a SSH_FXP_STATUS message.
-
-6.5 Removing and Renaming Files
-
- Files can be removed using the SSH_FXP_REMOVE message. It has the
- following format:
-
- uint32 id
- string filename [UTF-8]
-
- where `id' is the request identifier and `filename' is the name of
- the file to be removed. See Section ``File Names'' for more
- information. This request cannot be used to remove directories.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
- Files (and directories) can be renamed using the SSH_FXP_RENAME
- message. Its data is as follows:
-
- uint32 id
- string oldpath [UTF-8]
- string newpath [UTF-8]
-
- where `id' is the request identifier, `oldpath' is the name of an
- existing file or directory, and `newpath' is the new name for the
- file or directory. It is an error if there already exists a file
- with the name specified by newpath. The server may also fail rename
- requests in other situations, for example if `oldpath' and `newpath'
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 20]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- point to different file systems on the server.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message.
-
-6.6 Creating and Deleting Directories
-
- New directories can be created using the SSH_FXP_MKDIR request. It
- has the following format:
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier.
-
- `path' specifies the directory to be created. See Section ``File
- Names'' for more information on file names.
-
- `attrs' specifies the attributes that should be applied to it upon
- creation. Attributes are discussed in more detail in Section ``File
- Attributes''.
-
- The server will respond to this request with a SSH_FXP_STATUS
- message. If a file or directory with the specified path already
- exists, an error will be returned.
-
- Directories can be removed using the SSH_FXP_RMDIR request, which has
- the following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier, and `path' specifies the
- directory to be removed. See Section ``File Names'' for more
- information on file names.
-
- The server responds to this request with a SSH_FXP_STATUS message.
- Errors may be returned from this operation for various reasons,
- including, but not limited to, the path does not exist, the path does
- not refer to a directory object, the directory is not empty, or the
- user has insufficient access or permission to perform the requested
- operation.
-
-6.7 Scanning Directories
-
- The files in a directory can be listed using the SSH_FXP_OPENDIR and
- SSH_FXP_READDIR requests. Each SSH_FXP_READDIR request returns one
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 21]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- or more file names with full file attributes for each file. The
- client should call SSH_FXP_READDIR repeatedly until it has found the
- file it is looking for or until the server responds with a
- SSH_FXP_STATUS message indicating an error (normally SSH_FX_EOF if
- there are no more files in the directory). The client should then
- close the handle using the SSH_FXP_CLOSE request.
-
- The SSH_FXP_OPENDIR opens a directory for reading. It has the
- following format:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' is the path name of
- the directory to be listed (without any trailing slash). See Section
- ``File Names'' for more information on file names. This will return
- an error if the path does not specify a directory or if the directory
- is not readable. The server will respond to this request with either
- a SSH_FXP_HANDLE or a SSH_FXP_STATUS message.
-
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using SSH_FXP_READDIR
- requests. These are of the format
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is a handle
- returned by SSH_FXP_OPENDIR. (It is a protocol error to attempt to
- use an ordinary file handle returned by SSH_FXP_OPEN.)
-
- The server responds to this request with either a SSH_FXP_NAME or a
- SSH_FXP_STATUS message. One or more names may be returned at a time.
- Full status information is returned for each name in order to speed
- up typical directory listings.
-
- If there are no more names available to be read, the server MUST
- respond with a SSH_FXP_STATUS message with error code of SSH_FX_EOF.
-
- When the client no longer wishes to read more names from the
- directory, it SHOULD call SSH_FXP_CLOSE for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
-6.8 Retrieving File Attributes
-
- Very often, file attributes are automatically returned by
- SSH_FXP_READDIR. However, sometimes there is need to specifically
- retrieve the attributes for a named file. This can be done using the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 22]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- SSH_FXP_STAT, SSH_FXP_LSTAT and SSH_FXP_FSTAT requests.
-
- SSH_FXP_STAT and SSH_FXP_LSTAT only differ in that SSH_FXP_STAT
- follows symbolic links on the server, whereas SSH_FXP_LSTAT does not
- follow symbolic links. Both have the same format:
-
- uint32 id
- string path [UTF-8]
- uint32 flags
-
- where `id' is the request identifier, and `path' specifies the file
- system object for which status is to be returned. The server
- responds to this request with either SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
- The flags field specify the attribute flags in which the client has
- particular interest. This is a hint to the server. For example,
- because retrieving owner / group and acl information can be an
- expensive operation under some operating systems, the server may
- choose not to retrieve this information unless the client expresses a
- specific interest in it.
-
- The client has no guarantee the server will provide all the fields
- that it has expressed an interest in.
-
- SSH_FXP_FSTAT differs from the others in that it returns status
- information for an open file (identified by the file handle). Its
- format is as follows:
-
- uint32 id
- string handle
- uint32 flags
-
- where `id' is the request identifier and `handle' is a file handle
- returned by SSH_FXP_OPEN. The server responds to this request with
- SSH_FXP_ATTRS or SSH_FXP_STATUS.
-
-6.9 Setting File Attributes
-
- File attributes may be modified using the SSH_FXP_SETSTAT and
- SSH_FXP_FSETSTAT requests. These requests are used for operations
- such as changing the ownership, permissions or access times, as well
- as for truncating a file.
-
- The SSH_FXP_SETSTAT request is of the following format:
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 23]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string path [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `path' specifies the file
- system object (e.g. file or directory) whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''.
-
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes. The server responds to this request with a
- SSH_FXP_STATUS message.
-
- The SSH_FXP_FSETSTAT request modifies the attributes of a file which
- is already open. It has the following format:
-
- uint32 id
- string handle
- ATTRS attrs
-
- where `id' is the request identifier, `handle' (MUST be returned by
- SSH_FXP_OPEN) identifies the file whose attributes are to be
- modified, and `attrs' specifies the modifications to be made to its
- attributes. Attributes are discussed in more detail in Section
- ``File Attributes''. The server will respond to this request with
- SSH_FXP_STATUS.
-
-6.10 Dealing with Symbolic links
-
- The SSH_FXP_READLINK request may be used to read the target of a
- symbolic link. It would have a data part as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name of the symlink to be read.
-
- The server will respond with a SSH_FXP_NAME packet containing only
- one name and a dummy attributes value. The name in the returned
- packet contains the target of the link. If an error occurs, the
- server may respond with SSH_FXP_STATUS.
-
- The SSH_FXP_SYMLINK request will create a symbolic link on the
- server. It is of the following format
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 24]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- uint32 id
- string linkpath [UTF-8]
- string targetpath [UTF-8]
-
- where `id' is the request identifier, `linkpath' specifies the path
- name of the symlink to be created and `targetpath' specifies the
- target of the symlink. The server shall respond with a
- SSH_FXP_STATUS indicating either success (SSH_FX_OK) or an error
- condition.
-
-6.11 Canonicalizing the Server-Side Path Name
-
- The SSH_FXP_REALPATH request can be used to have the server
- canonicalize any given path name to an absolute path. This is useful
- for converting path names containing ".." components or relative
- pathnames without a leading slash into absolute paths. The format of
- the request is as follows:
-
- uint32 id
- string path [UTF-8]
-
- where `id' is the request identifier and `path' specifies the path
- name to be canonicalized. The server will respond with a
- SSH_FXP_NAME packet containing the name in canonical form and a dummy
- attributes value. If an error occurs, the server may also respond
- with SSH_FXP_STATUS.
-
-6.11.1 Best practice for dealing with paths
-
- The client SHOULD treat the results of SSH_FXP_REALPATH as a
- canonical absolute path, even if the path does not appear to be
- absolute. A client that use REALPATH(".") and treats the result as
- absolute, even if there is no leading slash, will continue to
- function correctly, even when talking to a Windows NT or VMS style
- system, where absolute paths may not begin with a slash.
-
- For example, if the client wishes to change directory up, and the
- server has returned "c:/x/y/z" from REALPATH, the client SHOULD use
- "c:/x/y/z/..".
-
- As a second example, if the client wishes to open the file "x.txt" in
- the current directory, and server has returned "dka100:/x/y/z" as the
- canonical path of the directory, the client SHOULD open "dka100:/x/y/
- z/x.txt"
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 25]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-7. Responses from the Server to the Client
-
- The server responds to the client using one of a few response
- packets. All requests can return a SSH_FXP_STATUS response upon
- failure. When the operation is successful, any of the responses may
- be returned (depending on the operation). If no data needs to be
- returned to the client, the SSH_FXP_STATUS response with SSH_FX_OK
- status is appropriate. Otherwise, the SSH_FXP_HANDLE message is used
- to return a file handle (for SSH_FXP_OPEN and SSH_FXP_OPENDIR
- requests), SSH_FXP_DATA is used to return data from SSH_FXP_READ,
- SSH_FXP_NAME is used to return one or more file names from a
- SSH_FXP_READDIR or SSH_FXP_REALPATH request, and SSH_FXP_ATTRS is
- used to return file attributes from SSH_FXP_STAT, SSH_FXP_LSTAT, and
- SSH_FXP_FSTAT requests.
-
- Exactly one response will be returned for each request. Each
- response packet contains a request identifier which can be used to
- match each response with the corresponding request. Note that it is
- legal to have several requests outstanding simultaneously, and the
- server is allowed to send responses to them in a different order from
- the order in which the requests were sent (the result of their
- execution, however, is guaranteed to be as if they had been processed
- one at a time in the order in which the requests were sent).
-
- Response packets are of the same general format as request packets.
- Each response packet begins with the request identifier.
-
- The format of the data portion of the SSH_FXP_STATUS response is as
- follows:
-
- uint32 id
- uint32 error/status code
- string error message (ISO-10646 UTF-8 [RFC-2279])
- string language tag (as defined in [RFC-1766])
-
- where `id' is the request identifier, and `error/status code'
- indicates the result of the requested operation. The value SSH_FX_OK
- indicates success, and all other values indicate failure.
-
- Currently, the following values are defined (other values may be
- defined by future versions of this protocol):
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 26]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- #define SSH_FX_OK 0
- #define SSH_FX_EOF 1
- #define SSH_FX_NO_SUCH_FILE 2
- #define SSH_FX_PERMISSION_DENIED 3
- #define SSH_FX_FAILURE 4
- #define SSH_FX_BAD_MESSAGE 5
- #define SSH_FX_NO_CONNECTION 6
- #define SSH_FX_CONNECTION_LOST 7
- #define SSH_FX_OP_UNSUPPORTED 8
- #define SSH_FX_INVALID_HANDLE 9
- #define SSH_FX_NO_SUCH_PATH 10
- #define SSH_FX_FILE_ALREADY_EXISTS 11
- #define SSH_FX_WRITE_PROTECT 12
- #define SSH_FX_NO_MEDIA 13
-
- SSH_FX_OK
- Indicates successful completion of the operation.
-
- SSH_FX_EOF
- indicates end-of-file condition; for SSH_FX_READ it means that no
- more data is available in the file, and for SSH_FX_READDIR it
- indicates that no more files are contained in the directory.
-
- SSH_FX_NO_SUCH_FILE
- is returned when a reference is made to a file which does not
- exist.
-
- SSH_FX_PERMISSION_DENIED
- is returned when the authenticated user does not have sufficient
- permissions to perform the operation.
-
- SSH_FX_FAILURE
- is a generic catch-all error message; it should be returned if an
- error occurs for which there is no more specific error code
- defined.
-
- SSH_FX_BAD_MESSAGE
- may be returned if a badly formatted packet or protocol
- incompatibility is detected.
-
- SSH_FX_NO_CONNECTION
- is a pseudo-error which indicates that the client has no
- connection to the server (it can only be generated locally by the
- client, and MUST NOT be returned by servers).
-
- SSH_FX_CONNECTION_LOST
- is a pseudo-error which indicates that the connection to the
- server has been lost (it can only be generated locally by the
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 27]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- client, and MUST NOT be returned by servers).
-
- SSH_FX_OP_UNSUPPORTED
- indicates that an attempt was made to perform an operation which
- is not supported for the server (it may be generated locally by
- the client if e.g. the version number exchange indicates that a
- required feature is not supported by the server, or it may be
- returned by the server if the server does not implement an
- operation).
-
- SSH_FX_INVALID_HANDLE
- The handle value was invalid.
-
- SSH_FX_NO_SUCH_PATH
- The file path does not exist or is invalid.
-
- SSH_FX_FILE_ALREADY_EXISTS
- The file already exists.
-
- SSH_FX_WRITE_PROTECT
- The file is on read only media, or the media is write protected.
-
- SSH_FX_NO_MEDIA
- The requested operation can not be completed because there is no
- media available in the drive.
-
- The SSH_FXP_HANDLE response has the following format:
-
- uint32 id
- string handle
-
- where `id' is the request identifier, and `handle' is an arbitrary
- string that identifies an open file or directory on the server. The
- handle is opaque to the client; the client MUST NOT attempt to
- interpret or modify it in any way. The length of the handle string
- MUST NOT exceed 256 data bytes.
-
- The SSH_FXP_DATA response has the following format:
-
- uint32 id
- string data
-
- where `id' is the request identifier, and `data' is an arbitrary byte
- string containing the requested data. The data string may be at most
- the number of bytes requested in a SSH_FXP_READ request, but may also
- be shorter if end of file is reached or if the read is from something
- other than a regular file.
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 28]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- The SSH_FXP_NAME response has the following format:
-
- uint32 id
- uint32 count
- repeats count times:
- string filename [UTF-8]
- ATTRS attrs
-
- where `id' is the request identifier, `count' is the number of names
- returned in this response, and the remaining fields repeat `count'
- times (so that all three fields are first included for the first
- file, then for the second file, etc). In the repeated part,
- `filename' is a file name being returned (for SSH_FXP_READDIR, it
- will be a relative name within the directory, without any path
- components; for SSH_FXP_REALPATH it will be an absolute path name),
- and `attrs' is the attributes of the file as described in Section
- ``File Attributes''.
-
- The SSH_FXP_ATTRS response has the following format:
-
- uint32 id
- ATTRS attrs
-
- where `id' is the request identifier, and `attrs' is the returned
- file attributes as described in Section ``File Attributes''.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 29]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-8. Vendor-Specific Extensions
-
- The SSH_FXP_EXTENDED request provides a generic extension mechanism
- for adding vendor-specific commands. The request has the following
- format:
-
- uint32 id
- string extended-request
- ... any request-specific data ...
-
- where `id' is the request identifier, and `extended-request' is a
- string of the format "name@domain", where domain is an internet
- domain name of the vendor defining the request. The rest of the
- request is completely vendor-specific, and servers should only
- attempt to interpret it if they recognize the `extended-request'
- name.
-
- The server may respond to such requests using any of the response
- packets defined in Section ``Responses from the Server to the
- Client''. Additionally, the server may also respond with a
- SSH_FXP_EXTENDED_REPLY packet, as defined below. If the server does
- not recognize the `extended-request' name, then the server MUST
- respond with SSH_FXP_STATUS with error/status set to
- SSH_FX_OP_UNSUPPORTED.
-
- The SSH_FXP_EXTENDED_REPLY packet can be used to carry arbitrary
- extension-specific data from the server to the client. It is of the
- following format:
-
- uint32 id
- ... any request-specific data ...
-
- There is a range of packet types reserved for use by extensions. In
- order to avoid collision, extensions that turn on the use of
- additional packet types should determine those numbers dynamically.
-
- The suggested way of doing this is have an extension request from the
- client to the server that enables the extension; the extension
- response from the server to the client would specify the actual type
- values to use, in additional to any other data.
-
- Extension authors should be mindful of the limited range of packet
- types available (there are only 45 values available) and avoid
- requiring a new packet type where possible.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 30]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-9. Security Considerations
-
- This protocol assumes that it is run over a secure channel and that
- the endpoints of the channel have been authenticated. Thus, this
- protocol assumes that it is externally protected from network-level
- attacks.
-
- This protocol provides file system access to arbitrary files on the
- server (only constrained by the server implementation). It is the
- responsibility of the server implementation to enforce any access
- controls that may be required to limit the access allowed for any
- particular user (the user being authenticated externally to this
- protocol, typically using the SSH User Authentication Protocol [8].
-
- Care must be taken in the server implementation to check the validity
- of received file handle strings. The server should not rely on them
- directly; it MUST check the validity of each handle before relying on
- it.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 31]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10. Changes from previous protocol versions
-
- The SSH File Transfer Protocol has changed over time, before it's
- standardization. The following is a description of the incompatible
- changes between different versions.
-
-10.1 Changes between versions 4 and 3
-
- Many of the changes between version 4 and version 3 are to the
- attribute structure to make it more flexible for non-unix platforms.
-
- o Clarify the use of stderr by the server.
-
- o Clarify handling of very large read requests by the server.
-
- o Make all filenames UTF-8.
-
- o Added 'newline' extension.
-
- o Made time fields 64 bit, and optionally have nanosecond resultion.
-
- o Made file attribute owner and group strings so they can actually
- be used on disparate systems.
-
- o Added createtime field, and added separate flags for atime,
- createtime, and mtime so they can be set separately.
-
- o Split the file type out of the permissions field and into it's own
- field (which is always present.)
-
- o Added acl attribute.
-
- o Added SSH_FXF_TEXT file open flag.
-
- o Added flags field to the get stat commands so that the client can
- specifically request information the server might not normally
- included for performance reasons.
-
- o Removed the long filename from the names structure-- it can now be
- built from information available in the attrs structure.
-
- o Added reserved range of packet numbers for extensions.
-
- o Added several additional error codes.
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 32]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-10.2 Changes between versions 3 and 2
-
- o The SSH_FXP_READLINK and SSH_FXP_SYMLINK messages were added.
-
- o The SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY messages were
- added.
-
- o The SSH_FXP_STATUS message was changed to include fields `error
- message' and `language tag'.
-
-
-10.3 Changes between versions 2 and 1
-
- o The SSH_FXP_RENAME message was added.
-
-
-10.4 Changes between versions 1 and 0
-
- o Implementation changes, no actual protocol changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 33]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-11. Trademark Issues
-
- "ssh" is a registered trademark of SSH Communications Security Corp
- in the United States and/or other countries.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 34]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-References
-
- [1] Dierks, T., Allen, C., Treese, W., Karlton, P., Freier, A. and
- P. Kocher, "The TLS Protocol Version 1.0", RFC 2246, January
- 1999.
-
- [2] Alvestrand, H., "IETF Policy on Character Sets and Languages",
- BCP 18, RFC 2277, January 1998.
-
- [3] Shepler, S., Callaghan, B., Robinson, D., Thurlow, R., Beame,
- C., Eisler, M. and D. Noveck, "NFS version 4 Protocol", RFC
- 3010, December 2000.
-
- [4] Institute of Electrical and Electronics Engineers, "Information
- Technology - Portable Operating System Interface (POSIX) - Part
- 1: System Application Program Interface (API) [C Language]",
- IEEE Standard 1003.2, 1996.
-
- [5] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Architecture",
- draft-ietf-secsh-architecture-13 (work in progress), September
- 2002.
-
- [6] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Protocol Transport Protocol",
- draft-ietf-secsh-transport-15 (work in progress), September
- 2002.
-
- [7] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Connection Protocol", draft-ietf-secsh-connect-16
- (work in progress), September 2002.
-
- [8] Rinne, T., Ylonen, T., Kivinen, T., Saarinen, M. and S.
- Lehtinen, "SSH Authentication Protocol",
- draft-ietf-secsh-userauth-16 (work in progress), September 2002.
-
-
-Authors' Addresses
-
- Joseph Galbraith
- VanDyke Software
- 4848 Tramway Ridge Blvd
- Suite 101
- Albuquerque, NM 87111
- US
-
- Phone: +1 505 332 5700
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 35]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Sami Lehtinen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 36]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 37]
-
-Internet-Draft SSH File Transfer Protocol December 2002
-
-
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgement
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Galbraith, et al. Expires June 18, 2003 [Page 38]
-
-
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
deleted file mode 100644
index d692285b4e..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.2.ps
+++ /dev/null
@@ -1,3205 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:14 2003
-%%Orientation: Portrait
-%%Pages: 15 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 31, 2004 D. Moffat, Editor, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( Oct 2003) s
-5 624 M
-( SSH Transport Layer Protocol) s
-5 613 M
-( draft-ietf-secsh-transport-17.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 31, 2004.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network.) s
-5 250 M
-( This document describes the SSH transport layer protocol which) s
-5 239 M
-( typically runs on top of TCP/IP. The protocol can be used as a basis) s
-5 228 M
-( for a number of secure network services. It provides strong) s
-5 217 M
-( encryption, server authentication, and integrity protection. It may) s
-5 206 M
-( also provide compression.) s
-5 184 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 173 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( all negotiated.) s
-5 668 M
-( This document also describes the Diffie-Hellman key exchange method) s
-5 657 M
-( and the minimal set of algorithms that are needed to implement the) s
-5 646 M
-( SSH transport layer protocol.) s
-5 624 M
-(Table of Contents) s
-5 602 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 591 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 580 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 569 M
-( 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 558 M
-( 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4) s
-5 547 M
-( 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4) s
-5 536 M
-( 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4) s
-5 525 M
-( 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5) s
-5 514 M
-( 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5) s
-5 503 M
-( 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5) s
-5 492 M
-( 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6) s
-5 481 M
-( 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 470 M
-( 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 459 M
-( 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9) s
-5 448 M
-( 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10) s
-5 437 M
-( 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11) s
-5 426 M
-( 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 415 M
-( 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13) s
-5 404 M
-( 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16) s
-5 393 M
-( 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17) s
-5 382 M
-( 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18) s
-5 371 M
-( 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19) s
-5 360 M
-( 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20) s
-5 349 M
-( 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21) s
-5 338 M
-( 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21) s
-5 327 M
-( 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22) s
-5 316 M
-( 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22) s
-5 305 M
-( 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23) s
-5 294 M
-( 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23) s
-5 283 M
-( 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23) s
-5 272 M
-( 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24) s
-5 261 M
-( 13. Security Considerations . . . . . . . . . . . . . . . . . . 24) s
-5 250 M
-( 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24) s
-5 239 M
-( 15. Additional Information . . . . . . . . . . . . . . . . . . . 24) s
-5 228 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26) s
-5 217 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 206 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 25) s
-5 195 M
-( A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27) s
-5 184 M
-( Intellectual Property and Copyright Statements . . . . . . . 28) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH transport layer is a secure low level transport protocol. It) s
-5 536 M
-( provides strong encryption, cryptographic host authentication, and) s
-5 525 M
-( integrity protection.) s
-5 503 M
-( Authentication in this protocol level is host-based; this protocol) s
-5 492 M
-( does not perform user authentication. A higher level protocol for) s
-5 481 M
-( user authentication can be designed on top of this protocol.) s
-5 459 M
-( The protocol has been designed to be simple, flexible, to allow) s
-5 448 M
-( parameter negotiation, and to minimize the number of round-trips.) s
-5 437 M
-( Key exchange method, public key algorithm, symmetric encryption) s
-5 426 M
-( algorithm, message authentication algorithm, and hash algorithm are) s
-5 415 M
-( all negotiated. It is expected that in most environments, only 2) s
-5 404 M
-( round-trips will be needed for full key exchange, server) s
-5 393 M
-( authentication, service request, and acceptance notification of) s
-5 382 M
-( service request. The worst case is 3 round-trips.) s
-5 360 M
-(3. Conventions Used in This Document) s
-5 338 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 327 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 316 M
-( described in [RFC2119].) s
-5 294 M
-( The used data types and terminology are specified in the architecture) s
-5 283 M
-( document [SSH-ARCH].) s
-5 261 M
-( The architecture document also discusses the algorithm naming) s
-5 250 M
-( conventions that MUST be used with the SSH protocols.) s
-5 228 M
-(4. Connection Setup) s
-5 206 M
-( SSH works over any 8-bit clean, binary-transparent transport. The) s
-5 195 M
-( underlying transport SHOULD protect against transmission errors as) s
-5 184 M
-( such errors cause the SSH connection to terminate.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The client initiates the connection.) s
-5 668 M
-(4.1 Use over TCP/IP) s
-5 646 M
-( When used over TCP/IP, the server normally listens for connections on) s
-5 635 M
-( port 22. This port number has been registered with the IANA, and has) s
-5 624 M
-( been officially assigned for SSH.) s
-5 602 M
-(4.2 Protocol Version Exchange) s
-5 580 M
-( When the connection has been established, both sides MUST send an) s
-5 569 M
-( identification string of the form "SSH-protoversion-softwareversion) s
-5 558 M
-( comments", followed by carriage return and newline characters \(ASCII) s
-5 547 M
-( 13 and 10, respectively\). Both sides MUST be able to process) s
-5 536 M
-( identification strings without carriage return character. No null) s
-5 525 M
-( character is sent. The maximum length of the string is 255) s
-5 514 M
-( characters, including the carriage return and newline.) s
-5 492 M
-( The part of the identification string preceding carriage return and) s
-5 481 M
-( newline is used in the Diffie-Hellman key exchange \(see Section) s
-5 470 M
-( Section 7\).) s
-5 448 M
-( The server MAY send other lines of data before sending the version) s
-5 437 M
-( string. Each line SHOULD be terminated by a carriage return and) s
-5 426 M
-( newline. Such lines MUST NOT begin with "SSH-", and SHOULD be) s
-5 415 M
-( encoded in ISO-10646 UTF-8 [RFC2279] \(language is not specified\).) s
-5 404 M
-( Clients MUST be able to process such lines; they MAY be silently) s
-5 393 M
-( ignored, or MAY be displayed to the client user; if they are) s
-5 382 M
-( displayed, control character filtering discussed in [SSH-ARCH] SHOULD) s
-5 371 M
-( be used. The primary use of this feature is to allow TCP-wrappers to) s
-5 360 M
-( display an error message before disconnecting.) s
-5 338 M
-( Version strings MUST consist of printable US-ASCII characters, not) s
-5 327 M
-( including whitespaces or a minus sign \(-\). The version string is) s
-5 316 M
-( primarily used to trigger compatibility extensions and to indicate) s
-5 305 M
-( the capabilities of an implementation. The comment string should) s
-5 294 M
-( contain additional information that might be useful in solving user) s
-5 283 M
-( problems.) s
-5 261 M
-( The protocol version described in this document is 2.0.) s
-5 239 M
-( Key exchange will begin immediately after sending this identifier.) s
-5 228 M
-( All packets following the identification string SHALL use the binary) s
-5 217 M
-( packet protocol, to be described below.) s
-5 195 M
-(4.3 Compatibility With Old SSH Versions) s
-5 173 M
-( During the transition period, it is important to be able to work in a) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( way that is compatible with the installed SSH clients and servers) s
-5 679 M
-( that use an older version of the protocol. Information in this) s
-5 668 M
-( section is only relevant for implementations supporting compatibility) s
-5 657 M
-( with SSH versions 1.x. There is no standards track or informational) s
-5 646 M
-( draft available that defines the SSH 1.x protocol. The only known) s
-5 635 M
-( documentation of the 1.x protocol is contained in README files that) s
-5 624 M
-( are shipped along with the source code.) s
-5 602 M
-(4.3.1 Old Client, New Server) s
-5 580 M
-( Server implementations MAY support a configurable "compatibility") s
-5 569 M
-( flag that enables compatibility with old versions. When this flag is) s
-5 558 M
-( on, the server SHOULD identify its protocol version as "1.99".) s
-5 547 M
-( Clients using protocol 2.0 MUST be able to identify this as identical) s
-5 536 M
-( to "2.0". In this mode the server SHOULD NOT send the carriage) s
-5 525 M
-( return character \(ASCII 13\) after the version identification string.) s
-5 503 M
-( In the compatibility mode the server SHOULD NOT send any further data) s
-5 492 M
-( after its initialization string until it has received an) s
-5 481 M
-( identification string from the client. The server can then determine) s
-5 470 M
-( whether the client is using an old protocol, and can revert to the) s
-5 459 M
-( old protocol if required. In the compatibility mode, the server MUST) s
-5 448 M
-( NOT send additional data before the version string.) s
-5 426 M
-( When compatibility with old clients is not needed, the server MAY) s
-5 415 M
-( send its initial key exchange data immediately after the) s
-5 404 M
-( identification string.) s
-5 382 M
-(4.3.2 New Client, Old Server) s
-5 360 M
-( Since the new client MAY immediately send additional data after its) s
-5 349 M
-( identification string \(before receiving server's identification\), the) s
-5 338 M
-( old protocol may already have been corrupted when the client learns) s
-5 327 M
-( that the server is old. When this happens, the client SHOULD close) s
-5 316 M
-( the connection to the server, and reconnect using the old protocol.) s
-5 294 M
-(5. Binary Packet Protocol) s
-5 272 M
-( Each packet is in the following format:) s
-5 250 M
-( uint32 packet_length) s
-5 239 M
-( byte padding_length) s
-5 228 M
-( byte[n1] payload; n1 = packet_length - padding_length - 1) s
-5 217 M
-( byte[n2] random padding; n2 = padding_length) s
-5 206 M
-( byte[m] mac \(message authentication code\); m = mac_length) s
-5 184 M
-( packet_length) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The length of the packet \(bytes\), not including MAC or the) s
-5 679 M
-( packet_length field itself.) s
-5 657 M
-( padding_length) s
-5 646 M
-( Length of padding \(bytes\).) s
-5 624 M
-( payload) s
-5 613 M
-( The useful contents of the packet. If compression has been) s
-5 602 M
-( negotiated, this field is compressed. Initially, compression) s
-5 591 M
-( MUST be "none".) s
-5 569 M
-( random padding) s
-5 558 M
-( Arbitrary-length padding, such that the total length of) s
-5 547 M
-( \(packet_length || padding_length || payload || padding\) is a) s
-5 536 M
-( multiple of the cipher block size or 8, whichever is larger.) s
-5 525 M
-( There MUST be at least four bytes of padding. The padding) s
-5 514 M
-( SHOULD consist of random bytes. The maximum amount of padding) s
-5 503 M
-( is 255 bytes.) s
-5 481 M
-( mac) s
-5 470 M
-( Message authentication code. If message authentication has) s
-5 459 M
-( been negotiated, this field contains the MAC bytes. Initially,) s
-5 448 M
-( the MAC algorithm MUST be "none".) s
-5 415 M
-( Note that length of the concatenation of packet length, padding) s
-5 404 M
-( length, payload, and padding MUST be a multiple of the cipher block) s
-5 393 M
-( size or 8, whichever is larger. This constraint MUST be enforced) s
-5 382 M
-( even when using stream ciphers. Note that the packet length field is) s
-5 371 M
-( also encrypted, and processing it requires special care when sending) s
-5 360 M
-( or receiving packets.) s
-5 338 M
-( The minimum size of a packet is 16 \(or the cipher block size,) s
-5 327 M
-( whichever is larger\) bytes \(plus MAC\); implementations SHOULD decrypt) s
-5 316 M
-( the length after receiving the first 8 \(or cipher block size,) s
-5 305 M
-( whichever is larger\) bytes of a packet.) s
-5 283 M
-(5.1 Maximum Packet Length) s
-5 261 M
-( All implementations MUST be able to process packets with uncompressed) s
-5 250 M
-( payload length of 32768 bytes or less and total packet size of 35000) s
-5 239 M
-( bytes or less \(including length, padding length, payload, padding,) s
-5 228 M
-( and MAC.\). The maximum of 35000 bytes is an arbitrary chosen value) s
-5 217 M
-( larger than uncompressed size. Implementations SHOULD support longer) s
-5 206 M
-( packets, where they might be needed, e.g. if an implementation wants) s
-5 195 M
-( to send a very large number of certificates. Such packets MAY be) s
-5 184 M
-( sent if the version string indicates that the other party is able to) s
-5 173 M
-( process them. However, implementations SHOULD check that the packet) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( length is reasonable for the implementation to avoid) s
-5 679 M
-( denial-of-service and/or buffer overflow attacks.) s
-5 657 M
-(5.2 Compression) s
-5 635 M
-( If compression has been negotiated, the payload field \(and only it\)) s
-5 624 M
-( will be compressed using the negotiated algorithm. The length field) s
-5 613 M
-( and MAC will be computed from the compressed payload. Encryption will) s
-5 602 M
-( be done after compression.) s
-5 580 M
-( Compression MAY be stateful, depending on the method. Compression) s
-5 569 M
-( MUST be independent for each direction, and implementations MUST) s
-5 558 M
-( allow independently choosing the algorithm for each direction.) s
-5 536 M
-( The following compression methods are currently defined:) s
-5 514 M
-( none REQUIRED no compression) s
-5 503 M
-( zlib OPTIONAL ZLIB \(LZ77\) compression) s
-5 481 M
-( The "zlib" compression is described in [RFC1950] and in [RFC1951].) s
-5 470 M
-( The compression context is initialized after each key exchange, and) s
-5 459 M
-( is passed from one packet to the next with only a partial flush being) s
-5 448 M
-( performed at the end of each packet. A partial flush means that the) s
-5 437 M
-( current compressed block is ended and all data will be output. If the) s
-5 426 M
-( current block is not a stored block, one or more empty blocks are) s
-5 415 M
-( added after the current block to ensure that there are at least 8) s
-5 404 M
-( bits counting from the start of the end-of-block code of the current) s
-5 393 M
-( block to the end of the packet payload.) s
-5 371 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 349 M
-(5.3 Encryption) s
-5 327 M
-( An encryption algorithm and a key will be negotiated during the key) s
-5 316 M
-( exchange. When encryption is in effect, the packet length, padding) s
-5 305 M
-( length, payload and padding fields of each packet MUST be encrypted) s
-5 294 M
-( with the given algorithm.) s
-5 272 M
-( The encrypted data in all packets sent in one direction SHOULD be) s
-5 261 M
-( considered a single data stream. For example, initialization vectors) s
-5 250 M
-( SHOULD be passed from the end of one packet to the beginning of the) s
-5 239 M
-( next packet. All ciphers SHOULD use keys with an effective key length) s
-5 228 M
-( of 128 bits or more.) s
-5 206 M
-( The ciphers in each direction MUST run independently of each other,) s
-5 195 M
-( and implementations MUST allow independently choosing the algorithm) s
-5 184 M
-( for each direction \(if multiple algorithms are allowed by local) s
-5 173 M
-( policy\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The following ciphers are currently defined:) s
-5 668 M
-( 3des-cbc REQUIRED three-key 3DES in CBC mode) s
-5 657 M
-( blowfish-cbc OPTIONALi Blowfish in CBC mode) s
-5 646 M
-( twofish256-cbc OPTIONAL Twofish in CBC mode,) s
-5 635 M
-( with 256-bit key) s
-5 624 M
-( twofish-cbc OPTIONAL alias for "twofish256-cbc" \(this) s
-5 613 M
-( is being retained for) s
-5 602 M
-( historical reasons\)) s
-5 591 M
-( twofish192-cbc OPTIONAL Twofish with 192-bit key) s
-5 580 M
-( twofish128-cbc OPTIONAL Twofish with 128-bit key) s
-5 569 M
-( aes256-cbc OPTIONAL AES \(Rijndael\) in CBC mode,) s
-5 558 M
-( with 256-bit key) s
-5 547 M
-( aes192-cbc OPTIONAL AES with 192-bit key) s
-5 536 M
-( aes128-cbc RECOMMENDED AES with 128-bit key) s
-5 525 M
-( serpent256-cbc OPTIONAL Serpent in CBC mode, with) s
-5 514 M
-( 256-bit key) s
-5 503 M
-( serpent192-cbc OPTIONAL Serpent with 192-bit key) s
-5 492 M
-( serpent128-cbc OPTIONAL Serpent with 128-bit key) s
-5 481 M
-( arcfour OPTIONAL the ARCFOUR stream cipher) s
-5 470 M
-( idea-cbc OPTIONAL IDEA in CBC mode) s
-5 459 M
-( cast128-cbc OPTIONAL CAST-128 in CBC mode) s
-5 448 M
-( none OPTIONAL no encryption; NOT RECOMMENDED) s
-5 426 M
-( The "3des-cbc" cipher is three-key triple-DES) s
-5 415 M
-( \(encrypt-decrypt-encrypt\), where the first 8 bytes of the key are) s
-5 404 M
-( used for the first encryption, the next 8 bytes for the decryption,) s
-5 393 M
-( and the following 8 bytes for the final encryption. This requires 24) s
-5 382 M
-( bytes of key data \(of which 168 bits are actually used\). To) s
-5 371 M
-( implement CBC mode, outer chaining MUST be used \(i.e., there is only) s
-5 360 M
-( one initialization vector\). This is a block cipher with 8 byte) s
-5 349 M
-( blocks. This algorithm is defined in [FIPS-46-3]) s
-5 327 M
-( The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys) s
-5 316 M
-( [SCHNEIER]. This is a block cipher with 8 byte blocks.) s
-5 294 M
-( The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,) s
-5 283 M
-( with 256 bit keys as described [TWOFISH]. This is a block cipher with) s
-5 272 M
-( 16 byte blocks.) s
-5 250 M
-( The "twofish192-cbc" cipher. Same as above but with 192-bit key.) s
-5 228 M
-( The "twofish128-cbc" cipher. Same as above but with 128-bit key.) s
-5 206 M
-( The "aes256-cbc" cipher is AES \(Advanced Encryption Standard\)) s
-5 195 M
-( [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit) s
-5 184 M
-( key.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "aes192-cbc" cipher. Same as above but with 192-bit key.) s
-5 668 M
-( The "aes128-cbc" cipher. Same as above but with 128-bit key.) s
-5 646 M
-( The "serpent256-cbc" cipher in CBC mode, with 256-bit key as) s
-5 635 M
-( described in the Serpent AES submission.) s
-5 613 M
-( The "serpent192-cbc" cipher. Same as above but with 192-bit key.) s
-5 591 M
-( The "serpent128-cbc" cipher. Same as above but with 128-bit key.) s
-5 569 M
-( The "arcfour" is the Arcfour stream cipher with 128 bit keys. The) s
-5 558 M
-( Arcfour cipher is believed to be compatible with the RC4 cipher) s
-5 547 M
-( [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.) s
-5 536 M
-( Arcfour \(and RC4\) has problems with weak keys, and should be used) s
-5 525 M
-( with caution.) s
-5 503 M
-( The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].) s
-5 481 M
-( The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode) s
-5 470 M
-( [RFC2144].) s
-5 448 M
-( The "none" algorithm specifies that no encryption is to be done.) s
-5 437 M
-( Note that this method provides no confidentiality protection, and it) s
-5 426 M
-( is not recommended. Some functionality \(e.g. password) s
-5 415 M
-( authentication\) may be disabled for security reasons if this cipher) s
-5 404 M
-( is chosen.) s
-5 382 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 360 M
-(5.4 Data Integrity) s
-5 338 M
-( Data integrity is protected by including with each packet a message) s
-5 327 M
-( authentication code \(MAC\) that is computed from a shared secret,) s
-5 316 M
-( packet sequence number, and the contents of the packet.) s
-5 294 M
-( The message authentication algorithm and key are negotiated during) s
-5 283 M
-( key exchange. Initially, no MAC will be in effect, and its length) s
-5 272 M
-( MUST be zero. After key exchange, the selected MAC will be computed) s
-5 261 M
-( before encryption from the concatenation of packet data:) s
-5 239 M
-( mac = MAC\(key, sequence_number || unencrypted_packet\)) s
-5 217 M
-( where unencrypted_packet is the entire packet without MAC \(the length) s
-5 206 M
-( fields, payload and padding\), and sequence_number is an implicit) s
-5 195 M
-( packet sequence number represented as uint32. The sequence number is) s
-5 184 M
-( initialized to zero for the first packet, and is incremented after) s
-5 173 M
-( every packet \(regardless of whether encryption or MAC is in use\). It) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( is never reset, even if keys/algorithms are renegotiated later. It) s
-5 679 M
-( wraps around to zero after every 2^32 packets. The packet sequence) s
-5 668 M
-( number itself is not included in the packet sent over the wire.) s
-5 646 M
-( The MAC algorithms for each direction MUST run independently, and) s
-5 635 M
-( implementations MUST allow choosing the algorithm independently for) s
-5 624 M
-( both directions.) s
-5 602 M
-( The MAC bytes resulting from the MAC algorithm MUST be transmitted) s
-5 591 M
-( without encryption as the last part of the packet. The number of MAC) s
-5 580 M
-( bytes depends on the algorithm chosen.) s
-5 558 M
-( The following MAC algorithms are currently defined:) s
-5 536 M
-( hmac-sha1 REQUIRED HMAC-SHA1 \(digest length = key) s
-5 525 M
-( length = 20\)) s
-5 514 M
-( hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 \(digest) s
-5 503 M
-( length = 12, key length = 20\)) s
-5 492 M
-( hmac-md5 OPTIONAL HMAC-MD5 \(digest length = key) s
-5 481 M
-( length = 16\)) s
-5 470 M
-( hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 \(digest) s
-5 459 M
-( length = 12, key length = 16\)) s
-5 448 M
-( none OPTIONAL no MAC; NOT RECOMMENDED) s
-5 426 M
-( Figure 1) s
-5 404 M
-( The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use) s
-5 393 M
-( only the first n bits of the resulting value.) s
-5 371 M
-( The hash algorithms are described in [SCHNEIER].) s
-5 349 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 327 M
-(5.5 Key Exchange Methods) s
-5 305 M
-( The key exchange method specifies how one-time session keys are) s
-5 294 M
-( generated for encryption and for authentication, and how the server) s
-5 283 M
-( authentication is done.) s
-5 261 M
-( Only one REQUIRED key exchange method has been defined:) s
-5 239 M
-( diffie-hellman-group1-sha1 REQUIRED) s
-5 217 M
-( This method is described later in this document.) s
-5 195 M
-( Additional methods may be defined as specified in [SSH-ARCH].) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(5.6 Public Key Algorithms) s
-5 668 M
-( This protocol has been designed to be able to operate with almost any) s
-5 657 M
-( public key format, encoding, and algorithm \(signature and/or) s
-5 646 M
-( encryption\).) s
-5 624 M
-( There are several aspects that define a public key type:) s
-5 613 M
-( o Key format: how is the key encoded and how are certificates) s
-5 602 M
-( represented. The key blobs in this protocol MAY contain) s
-5 591 M
-( certificates in addition to keys.) s
-5 580 M
-( o Signature and/or encryption algorithms. Some key types may not) s
-5 569 M
-( support both signing and encryption. Key usage may also be) s
-5 558 M
-( restricted by policy statements in e.g. certificates. In this) s
-5 547 M
-( case, different key types SHOULD be defined for the different) s
-5 536 M
-( policy alternatives.) s
-5 525 M
-( o Encoding of signatures and/or encrypted data. This includes but is) s
-5 514 M
-( not limited to padding, byte order, and data formats.) s
-5 492 M
-( The following public key and/or certificate formats are currently defined:) s
-5 470 M
-( ssh-dss REQUIRED sign Raw DSS Key) s
-5 459 M
-( ssh-rsa RECOMMENDED sign Raw RSA Key) s
-5 448 M
-( x509v3-sign-rsa OPTIONAL sign X.509 certificates \(RSA key\)) s
-5 437 M
-( x509v3-sign-dss OPTIONAL sign X.509 certificates \(DSS key\)) s
-5 426 M
-( spki-sign-rsa OPTIONAL sign SPKI certificates \(RSA key\)) s
-5 415 M
-( spki-sign-dss OPTIONAL sign SPKI certificates \(DSS key\)) s
-5 404 M
-( pgp-sign-rsa OPTIONAL sign OpenPGP certificates \(RSA key\)) s
-5 393 M
-( pgp-sign-dss OPTIONAL sign OpenPGP certificates \(DSS key\)) s
-5 371 M
-( Additional key types may be defined as specified in [SSH-ARCH].) s
-5 349 M
-( The key type MUST always be explicitly known \(from algorithm) s
-5 338 M
-( negotiation or some other source\). It is not normally included in) s
-5 327 M
-( the key blob.) s
-5 305 M
-( Certificates and public keys are encoded as follows:) s
-5 283 M
-( string certificate or public key format identifier) s
-5 272 M
-( byte[n] key/certificate data) s
-5 250 M
-( The certificate part may have be a zero length string, but a public) s
-5 239 M
-( key is required. This is the public key that will be used for) s
-5 228 M
-( authentication; the certificate sequence contained in the certificate) s
-5 217 M
-( blob can be used to provide authorization.) s
-5 195 M
-( Public key / certifcate formats that do not explicitly specify a) s
-5 184 M
-( signature format identifier MUST use the public key / certificate) s
-5 173 M
-( format identifier as the signature identifier.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Signatures are encoded as follows:) s
-5 679 M
-( string signature format identifier \(as specified by the) s
-5 668 M
-( public key / cert format\)) s
-5 657 M
-( byte[n] signature blob in format specific encoding.) s
-5 624 M
-( The "ssh-dss" key format has the following specific encoding:) s
-5 602 M
-( string "ssh-dss") s
-5 591 M
-( mpint p) s
-5 580 M
-( mpint q) s
-5 569 M
-( mpint g) s
-5 558 M
-( mpint y) s
-5 536 M
-( Here the p, q, g, and y parameters form the signature key blob.) s
-5 514 M
-( Signing and verifying using this key format is done according to the) s
-5 503 M
-( Digital Signature Standard [FIPS-186] using the SHA-1 hash. A) s
-5 492 M
-( description can also be found in [SCHNEIER].) s
-5 470 M
-( The resulting signature is encoded as follows:) s
-5 448 M
-( string "ssh-dss") s
-5 437 M
-( string dss_signature_blob) s
-5 415 M
-( dss_signature_blob is encoded as a string containing r followed by s) s
-5 404 M
-( \(which are 160 bits long integers, without lengths or padding,) s
-5 393 M
-( unsigned and in network byte order\).) s
-5 371 M
-( The "ssh-rsa" key format has the following specific encoding:) s
-5 349 M
-( string "ssh-rsa") s
-5 338 M
-( mpint e) s
-5 327 M
-( mpint n) s
-5 305 M
-( Here the e and n parameters form the signature key blob.) s
-5 283 M
-( Signing and verifying using this key format is done according to) s
-5 272 M
-( [SCHNEIER] and [PKCS1] using the SHA-1 hash.) s
-5 250 M
-( The resulting signature is encoded as follows:) s
-5 228 M
-( string "ssh-rsa") s
-5 217 M
-( string rsa_signature_blob) s
-5 195 M
-( rsa_signature_blob is encoded as a string containing s \(which is an) s
-5 184 M
-( integer, without lengths or padding, unsigned and in network byte) s
-5 173 M
-( order\).) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( The "spki-sign-rsa" method indicates that the certificate blob) s
-5 679 M
-( contains a sequence of SPKI certificates. The format of SPKI) s
-5 668 M
-( certificates is described in [RFC2693]. This method indicates that) s
-5 657 M
-( the key \(or one of the keys in the certificate\) is an RSA-key.) s
-5 635 M
-( The "spki-sign-dss". As above, but indicates that the key \(or one of) s
-5 624 M
-( the keys in the certificate\) is a DSS-key.) s
-5 602 M
-( The "pgp-sign-rsa" method indicates the certificates, the public key,) s
-5 591 M
-( and the signature are in OpenPGP compatible binary format) s
-5 580 M
-( \([RFC2440]\). This method indicates that the key is an RSA-key.) s
-5 558 M
-( The "pgp-sign-dss". As above, but indicates that the key is a) s
-5 547 M
-( DSS-key.) s
-5 525 M
-(6. Key Exchange) s
-5 503 M
-( Key exchange begins by each side sending lists of supported) s
-5 492 M
-( algorithms. Each side has a preferred algorithm in each category, and) s
-5 481 M
-( it is assumed that most implementations at any given time will use) s
-5 470 M
-( the same preferred algorithm. Each side MAY guess which algorithm) s
-5 459 M
-( the other side is using, and MAY send an initial key exchange packet) s
-5 448 M
-( according to the algorithm if appropriate for the preferred method.) s
-5 426 M
-( Guess is considered wrong, if:) s
-5 415 M
-( o the kex algorithm and/or the host key algorithm is guessed wrong) s
-5 404 M
-( \(server and client have different preferred algorithm\), or) s
-5 393 M
-( o if any of the other algorithms cannot be agreed upon \(the) s
-5 382 M
-( procedure is defined below in Section Section 6.1\).) s
-5 360 M
-( Otherwise, the guess is considered to be right and the optimistically) s
-5 349 M
-( sent packet MUST be handled as the first key exchange packet.) s
-5 327 M
-( However, if the guess was wrong, and a packet was optimistically sent) s
-5 316 M
-( by one or both parties, such packets MUST be ignored \(even if the) s
-5 305 M
-( error in the guess would not affect the contents of the initial) s
-5 294 M
-( packet\(s\)\), and the appropriate side MUST send the correct initial) s
-5 283 M
-( packet.) s
-5 261 M
-( Server authentication in the key exchange MAY be implicit. After a) s
-5 250 M
-( key exchange with implicit server authentication, the client MUST) s
-5 239 M
-( wait for response to its service request message before sending any) s
-5 228 M
-( further data.) s
-5 206 M
-(6.1 Algorithm Negotiation) s
-5 184 M
-( Key exchange begins by each side sending the following packet:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXINIT) s
-5 679 M
-( byte[16] cookie \(random bytes\)) s
-5 668 M
-( string kex_algorithms) s
-5 657 M
-( string server_host_key_algorithms) s
-5 646 M
-( string encryption_algorithms_client_to_server) s
-5 635 M
-( string encryption_algorithms_server_to_client) s
-5 624 M
-( string mac_algorithms_client_to_server) s
-5 613 M
-( string mac_algorithms_server_to_client) s
-5 602 M
-( string compression_algorithms_client_to_server) s
-5 591 M
-( string compression_algorithms_server_to_client) s
-5 580 M
-( string languages_client_to_server) s
-5 569 M
-( string languages_server_to_client) s
-5 558 M
-( boolean first_kex_packet_follows) s
-5 547 M
-( uint32 0 \(reserved for future extension\)) s
-5 525 M
-( Each of the algorithm strings MUST be a comma-separated list of) s
-5 514 M
-( algorithm names \(see ''Algorithm Naming'' in [SSH-ARCH]\). Each) s
-5 503 M
-( supported \(allowed\) algorithm MUST be listed in order of preference.) s
-5 481 M
-( The first algorithm in each list MUST be the preferred \(guessed\)) s
-5 470 M
-( algorithm. Each string MUST contain at least one algorithm name.) s
-5 437 M
-( cookie) s
-5 426 M
-( The cookie MUST be a random value generated by the sender. Its) s
-5 415 M
-( purpose is to make it impossible for either side to fully) s
-5 404 M
-( determine the keys and the session identifier.) s
-5 382 M
-( kex_algorithms) s
-5 371 M
-( Key exchange algorithms were defined above. The first) s
-5 360 M
-( algorithm MUST be the preferred \(and guessed\) algorithm. If) s
-5 349 M
-( both sides make the same guess, that algorithm MUST be used.) s
-5 338 M
-( Otherwise, the following algorithm MUST be used to choose a key) s
-5 327 M
-( exchange method: iterate over client's kex algorithms, one at a) s
-5 316 M
-( time. Choose the first algorithm that satisfies the following) s
-5 305 M
-( conditions:) s
-5 294 M
-( + the server also supports the algorithm,) s
-5 283 M
-( + if the algorithm requires an encryption-capable host key,) s
-5 272 M
-( there is an encryption-capable algorithm on the server's) s
-5 261 M
-( server_host_key_algorithms that is also supported by the) s
-5 250 M
-( client, and) s
-5 239 M
-( + if the algorithm requires a signature-capable host key,) s
-5 228 M
-( there is a signature-capable algorithm on the server's) s
-5 217 M
-( server_host_key_algorithms that is also supported by the) s
-5 206 M
-( client.) s
-5 195 M
-( + If no algorithm satisfying all these conditions can be) s
-5 184 M
-( found, the connection fails, and both sides MUST disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( server_host_key_algorithms) s
-5 679 M
-( List of the algorithms supported for the server host key. The) s
-5 668 M
-( server lists the algorithms for which it has host keys; the) s
-5 657 M
-( client lists the algorithms that it is willing to accept.) s
-5 646 M
-( \(There MAY be multiple host keys for a host, possibly with) s
-5 635 M
-( different algorithms.\)) s
-5 613 M
-( Some host keys may not support both signatures and encryption) s
-5 602 M
-( \(this can be determined from the algorithm\), and thus not all) s
-5 591 M
-( host keys are valid for all key exchange methods.) s
-5 569 M
-( Algorithm selection depends on whether the chosen key exchange) s
-5 558 M
-( algorithm requires a signature or encryption capable host key.) s
-5 547 M
-( It MUST be possible to determine this from the public key) s
-5 536 M
-( algorithm name. The first algorithm on the client's list that) s
-5 525 M
-( satisfies the requirements and is also supported by the server) s
-5 514 M
-( MUST be chosen. If there is no such algorithm, both sides MUST) s
-5 503 M
-( disconnect.) s
-5 481 M
-( encryption_algorithms) s
-5 470 M
-( Lists the acceptable symmetric encryption algorithms in order) s
-5 459 M
-( of preference. The chosen encryption algorithm to each) s
-5 448 M
-( direction MUST be the first algorithm on the client's list) s
-5 437 M
-( that is also on the server's list. If there is no such) s
-5 426 M
-( algorithm, both sides MUST disconnect.) s
-5 404 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 393 M
-( acceptable. The defined algorithm names are listed in Section) s
-5 382 M
-( Section 5.3.) s
-5 360 M
-( mac_algorithms) s
-5 349 M
-( Lists the acceptable MAC algorithms in order of preference.) s
-5 338 M
-( The chosen MAC algorithm MUST be the first algorithm on the) s
-5 327 M
-( client's list that is also on the server's list. If there is) s
-5 316 M
-( no such algorithm, both sides MUST disconnect.) s
-5 294 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 283 M
-( acceptable. The MAC algorithm names are listed in Section) s
-5 272 M
-( Figure 1.) s
-5 250 M
-( compression_algorithms) s
-5 239 M
-( Lists the acceptable compression algorithms in order of) s
-5 228 M
-( preference. The chosen compression algorithm MUST be the first) s
-5 217 M
-( algorithm on the client's list that is also on the server's) s
-5 206 M
-( list. If there is no such algorithm, both sides MUST) s
-5 195 M
-( disconnect.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( Note that "none" must be explicitly listed if it is to be) s
-5 679 M
-( acceptable. The compression algorithm names are listed in) s
-5 668 M
-( Section Section 5.2.) s
-5 646 M
-( languages) s
-5 635 M
-( This is a comma-separated list of language tags in order of) s
-5 624 M
-( preference [RFC3066]. Both parties MAY ignore this list. If) s
-5 613 M
-( there are no language preferences, this list SHOULD be empty.) s
-5 602 M
-( Language tags SHOULD NOT be present unless they are known to be) s
-5 591 M
-( needed by the sending party.) s
-5 569 M
-( first_kex_packet_follows) s
-5 558 M
-( Indicates whether a guessed key exchange packet follows. If a) s
-5 547 M
-( guessed packet will be sent, this MUST be TRUE. If no guessed) s
-5 536 M
-( packet will be sent, this MUST be FALSE.) s
-5 514 M
-( After receiving the SSH_MSG_KEXINIT packet from the other side,) s
-5 503 M
-( each party will know whether their guess was right. If the) s
-5 492 M
-( other party's guess was wrong, and this field was TRUE, the) s
-5 481 M
-( next packet MUST be silently ignored, and both sides MUST then) s
-5 470 M
-( act as determined by the negotiated key exchange method. If) s
-5 459 M
-( the guess was right, key exchange MUST continue using the) s
-5 448 M
-( guessed packet.) s
-5 426 M
-( After the KEXINIT packet exchange, the key exchange algorithm is run.) s
-5 415 M
-( It may involve several packet exchanges, as specified by the key) s
-5 404 M
-( exchange method.) s
-5 382 M
-(6.2 Output from Key Exchange) s
-5 360 M
-( The key exchange produces two values: a shared secret K, and an) s
-5 349 M
-( exchange hash H. Encryption and authentication keys are derived from) s
-5 338 M
-( these. The exchange hash H from the first key exchange is) s
-5 327 M
-( additionally used as the session identifier, which is a unique) s
-5 316 M
-( identifier for this connection. It is used by authentication methods) s
-5 305 M
-( as a part of the data that is signed as a proof of possession of a) s
-5 294 M
-( private key. Once computed, the session identifier is not changed,) s
-5 283 M
-( even if keys are later re-exchanged.) s
-5 250 M
-( Each key exchange method specifies a hash function that is used in) s
-5 239 M
-( the key exchange. The same hash algorithm MUST be used in key) s
-5 228 M
-( derivation. Here, we'll call it HASH.) s
-5 195 M
-( Encryption keys MUST be computed as HASH of a known value and K as) s
-5 184 M
-( follows:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (16,17) 9
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 17 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( o Initial IV client to server: HASH\(K || H || "A" || session_id\)) s
-5 679 M
-( \(Here K is encoded as mpint and "A" as byte and session_id as raw) s
-5 668 M
-( data."A" means the single character A, ASCII 65\).) s
-5 657 M
-( o Initial IV server to client: HASH\(K || H || "B" || session_id\)) s
-5 646 M
-( o Encryption key client to server: HASH\(K || H || "C" || session_id\)) s
-5 635 M
-( o Encryption key server to client: HASH\(K || H || "D" || session_id\)) s
-5 624 M
-( o Integrity key client to server: HASH\(K || H || "E" || session_id\)) s
-5 613 M
-( o Integrity key server to client: HASH\(K || H || "F" || session_id\)) s
-5 591 M
-( Key data MUST be taken from the beginning of the hash output. 128) s
-5 580 M
-( bits \(16 bytes\) MUST be used for algorithms with variable-length) s
-5 569 M
-( keys. The only variable key length algorithm defined in this document) s
-5 558 M
-( is arcfour\). For other algorithms, as many bytes as are needed are) s
-5 547 M
-( taken from the beginning of the hash value. If the key length needed) s
-5 536 M
-( is longer than the output of the HASH, the key is extended by) s
-5 525 M
-( computing HASH of the concatenation of K and H and the entire key so) s
-5 514 M
-( far, and appending the resulting bytes \(as many as HASH generates\) to) s
-5 503 M
-( the key. This process is repeated until enough key material is) s
-5 492 M
-( available; the key is taken from the beginning of this value. In) s
-5 481 M
-( other words:) s
-5 459 M
-( K1 = HASH\(K || H || X || session_id\) \(X is e.g. "A"\)) s
-5 448 M
-( K2 = HASH\(K || H || K1\)) s
-5 437 M
-( K3 = HASH\(K || H || K1 || K2\)) s
-5 426 M
-( ...) s
-5 415 M
-( key = K1 || K2 || K3 || ...) s
-5 393 M
-( This process will lose entropy if the amount of entropy in K is) s
-5 382 M
-( larger than the internal state size of HASH.) s
-5 360 M
-(6.3 Taking Keys Into Use) s
-5 338 M
-( Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.) s
-5 327 M
-( This message is sent with the old keys and algorithms. All messages) s
-5 316 M
-( sent after this message MUST use the new keys and algorithms.) s
-5 283 M
-( When this message is received, the new keys and algorithms MUST be) s
-5 272 M
-( taken into use for receiving.) s
-5 239 M
-( This message is the only valid message after key exchange, in) s
-5 228 M
-( addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE) s
-5 217 M
-( messages. The purpose of this message is to ensure that a party is) s
-5 206 M
-( able to respond with a disconnect message that the other party can) s
-5 195 M
-( understand if something goes wrong with the key exchange.) s
-5 184 M
-( Implementations MUST NOT accept any other messages after key exchange) s
-5 173 M
-( before receiving SSH_MSG_NEWKEYS.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 18 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_NEWKEYS) s
-5 657 M
-(7. Diffie-Hellman Key Exchange) s
-5 635 M
-( The Diffie-Hellman key exchange provides a shared secret that can not) s
-5 624 M
-( be determined by either party alone. The key exchange is combined) s
-5 613 M
-( with a signature with the host key to provide host authentication.) s
-5 580 M
-( In the following description \(C is the client, S is the server; p is) s
-5 569 M
-( a large safe prime, g is a generator for a subgroup of GF\(p\), and q) s
-5 558 M
-( is the order of the subgroup; V_S is S's version string; V_C is C's) s
-5 547 M
-( version string; K_S is S's public host key; I_C is C's KEXINIT) s
-5 536 M
-( message and I_S S's KEXINIT message which have been exchanged before) s
-5 525 M
-( this part begins\):) s
-5 492 M
-( 1. C generates a random number x \(1 < x < q\) and computes e = g^x) s
-5 481 M
-( mod p. C sends "e" to S.) s
-5 459 M
-( 2. S generates a random number y \(0 < y < q\) and computes f = g^y) s
-5 448 M
-( mod p. S receives "e". It computes K = e^y mod p, H = hash\(V_C) s
-5 437 M
-( || V_S || I_C || I_S || K_S || e || f || K\) \(these elements are) s
-5 426 M
-( encoded according to their types; see below\), and signature s on) s
-5 415 M
-( H with its private host key. S sends "K_S || f || s" to C. The) s
-5 404 M
-( signing operation may involve a second hashing operation.) s
-5 382 M
-( 3. C verifies that K_S really is the host key for S \(e.g. using) s
-5 371 M
-( certificates or a local database\). C is also allowed to accept) s
-5 360 M
-( the key without verification; however, doing so will render the) s
-5 349 M
-( protocol insecure against active attacks \(but may be desirable) s
-5 338 M
-( for practical reasons in the short term in many environments\). C) s
-5 327 M
-( then computes K = f^x mod p, H = hash\(V_C || V_S || I_C || I_S ||) s
-5 316 M
-( K_S || e || f || K\), and verifies the signature s on H.) s
-5 294 M
-( Either side MUST NOT send or accept e or f values that are not in the) s
-5 283 M
-( range [1, p-1]. If this condition is violated, the key exchange) s
-5 272 M
-( fails.) s
-5 239 M
-( This is implemented with the following messages. The hash algorithm) s
-5 228 M
-( for computing the exchange hash is defined by the method name, and is) s
-5 217 M
-( called HASH. The public key algorithm for signing is negotiated with) s
-5 206 M
-( the KEXINIT messages.) s
-5 184 M
-( First, the client sends the following:) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (18,19) 10
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 19 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( byte SSH_MSG_KEXDH_INIT) s
-5 679 M
-( mpint e) s
-5 646 M
-( The server responds with the following:) s
-5 624 M
-( byte SSH_MSG_KEXDH_REPLY) s
-5 613 M
-( string server public host key and certificates \(K_S\)) s
-5 602 M
-( mpint f) s
-5 591 M
-( string signature of H) s
-5 569 M
-( The hash H is computed as the HASH hash of the concatenation of the) s
-5 558 M
-( following:) s
-5 536 M
-( string V_C, the client's version string \(CR and NL excluded\)) s
-5 525 M
-( string V_S, the server's version string \(CR and NL excluded\)) s
-5 514 M
-( string I_C, the payload of the client's SSH_MSG_KEXINIT) s
-5 503 M
-( string I_S, the payload of the server's SSH_MSG_KEXINIT) s
-5 492 M
-( string K_S, the host key) s
-5 481 M
-( mpint e, exchange value sent by the client) s
-5 470 M
-( mpint f, exchange value sent by the server) s
-5 459 M
-( mpint K, the shared secret) s
-5 437 M
-( This value is called the exchange hash, and it is used to) s
-5 426 M
-( authenticate the key exchange. The exchange hash SHOULD be kept) s
-5 415 M
-( secret.) s
-5 382 M
-( The signature algorithm MUST be applied over H, not the original) s
-5 371 M
-( data. Most signature algorithms include hashing and additional) s
-5 360 M
-( padding. For example, "ssh-dss" specifies SHA-1 hashing; in that) s
-5 349 M
-( case, the data is first hashed with HASH to compute H, and H is then) s
-5 338 M
-( hashed with SHA-1 as part of the signing operation.) s
-5 316 M
-(7.1 diffie-hellman-group1-sha1) s
-5 294 M
-( The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key) s
-5 283 M
-( exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] \(2048-bit) s
-5 272 M
-( MODP Group\). It is included below in hexadecimal and decimal.) s
-5 250 M
-( The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor\( 2^894 Pi +) s
-5 239 M
-( 129093 \). Its hexadecimal value is:) s
-5 217 M
-( FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1) s
-5 206 M
-( 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD) s
-5 195 M
-( EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245) s
-5 184 M
-( E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED) s
-5 173 M
-( EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 20 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( FFFFFFFF FFFFFFFF.) s
-5 668 M
-( In decimal, this value is:) s
-5 646 M
-( 179769313486231590770839156793787453197860296048756011706444) s
-5 635 M
-( 423684197180216158519368947833795864925541502180565485980503) s
-5 624 M
-( 646440548199239100050792877003355816639229553136239076508735) s
-5 613 M
-( 759914822574862575007425302077447712589550957937778424442426) s
-5 602 M
-( 617334727629299387668709205606050270810842907692932019128194) s
-5 591 M
-( 467627007.) s
-5 569 M
-( The generator used with this prime is g = 2. The group order q is \(p) s
-5 558 M
-( - 1\) / 2.) s
-5 536 M
-(8. Key Re-Exchange) s
-5 514 M
-( Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when) s
-5 503 M
-( not already doing a key exchange \(as described in Section Section) s
-5 492 M
-( 6.1\). When this message is received, a party MUST respond with its) s
-5 481 M
-( own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT) s
-5 470 M
-( already was a reply. Either party MAY initiate the re-exchange, but) s
-5 459 M
-( roles MUST NOT be changed \(i.e., the server remains the server, and) s
-5 448 M
-( the client remains the client\).) s
-5 415 M
-( Key re-exchange is performed using whatever encryption was in effect) s
-5 404 M
-( when the exchange was started. Encryption, compression, and MAC) s
-5 393 M
-( methods are not changed before a new SSH_MSG_NEWKEYS is sent after) s
-5 382 M
-( the key exchange \(as in the initial key exchange\). Re-exchange is) s
-5 371 M
-( processed identically to the initial key exchange, except for the) s
-5 360 M
-( session identifier that will remain unchanged. It is permissible to) s
-5 349 M
-( change some or all of the algorithms during the re-exchange. Host) s
-5 338 M
-( keys can also change. All keys and initialization vectors are) s
-5 327 M
-( recomputed after the exchange. Compression and encryption contexts) s
-5 316 M
-( are reset.) s
-5 283 M
-( It is recommended that the keys are changed after each gigabyte of) s
-5 272 M
-( transmitted data or after each hour of connection time, whichever) s
-5 261 M
-( comes sooner. However, since the re-exchange is a public key) s
-5 250 M
-( operation, it requires a fair amount of processing power and should) s
-5 239 M
-( not be performed too often.) s
-5 206 M
-( More application data may be sent after the SSH_MSG_NEWKEYS packet) s
-5 195 M
-( has been sent; key exchange does not affect the protocols that lie) s
-5 184 M
-( above the SSH transport layer.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (20,21) 11
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 21 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(9. Service Request) s
-5 668 M
-( After the key exchange, the client requests a service. The service is) s
-5 657 M
-( identified by a name. The format of names and procedures for defining) s
-5 646 M
-( new names are defined in [SSH-ARCH].) s
-5 613 M
-( Currently, the following names have been reserved:) s
-5 591 M
-( ssh-userauth) s
-5 580 M
-( ssh-connection) s
-5 558 M
-( Similar local naming policy is applied to the service names, as is) s
-5 547 M
-( applied to the algorithm names; a local service should use the) s
-5 536 M
-( "servicename@domain" syntax.) s
-5 514 M
-( byte SSH_MSG_SERVICE_REQUEST) s
-5 503 M
-( string service name) s
-5 481 M
-( If the server rejects the service request, it SHOULD send an) s
-5 470 M
-( appropriate SSH_MSG_DISCONNECT message and MUST disconnect.) s
-5 437 M
-( When the service starts, it may have access to the session identifier) s
-5 426 M
-( generated during the key exchange.) s
-5 393 M
-( If the server supports the service \(and permits the client to use) s
-5 382 M
-( it\), it MUST respond with the following:) s
-5 360 M
-( byte SSH_MSG_SERVICE_ACCEPT) s
-5 349 M
-( string service name) s
-5 327 M
-( Message numbers used by services should be in the area reserved for) s
-5 316 M
-( them \(see Section 6 in [SSH-ARCH]\). The transport level will) s
-5 305 M
-( continue to process its own messages.) s
-5 272 M
-( Note that after a key exchange with implicit server authentication,) s
-5 261 M
-( the client MUST wait for response to its service request message) s
-5 250 M
-( before sending any further data.) s
-5 228 M
-(10. Additional Messages) s
-5 206 M
-( Either party may send any of the following messages at any time.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 22 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.1 Disconnection Message) s
-5 668 M
-( byte SSH_MSG_DISCONNECT) s
-5 657 M
-( uint32 reason code) s
-5 646 M
-( string description [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( This message causes immediate termination of the connection. All) s
-5 602 M
-( implementations MUST be able to process this message; they SHOULD be) s
-5 591 M
-( able to send this message.) s
-5 569 M
-( The sender MUST NOT send or receive any data after this message, and) s
-5 558 M
-( the recipient MUST NOT accept any data after receiving this message.) s
-5 547 M
-( The description field gives a more specific explanation in a) s
-5 536 M
-( human-readable form. The error code gives the reason in a more) s
-5 525 M
-( machine-readable format \(suitable for localization\), and can have the) s
-5 514 M
-( following values:) s
-5 492 M
-( #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1) s
-5 481 M
-( #define SSH_DISCONNECT_PROTOCOL_ERROR 2) s
-5 470 M
-( #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3) s
-5 459 M
-( #define SSH_DISCONNECT_RESERVED 4) s
-5 448 M
-( #define SSH_DISCONNECT_MAC_ERROR 5) s
-5 437 M
-( #define SSH_DISCONNECT_COMPRESSION_ERROR 6) s
-5 426 M
-( #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7) s
-5 415 M
-( #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8) s
-5 404 M
-( #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9) s
-5 393 M
-( #define SSH_DISCONNECT_CONNECTION_LOST 10) s
-5 382 M
-( #define SSH_DISCONNECT_BY_APPLICATION 11) s
-5 371 M
-( #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12) s
-5 360 M
-( #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13) s
-5 349 M
-( #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14) s
-5 338 M
-( #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15) s
-5 316 M
-( If the description string is displayed, control character filtering) s
-5 305 M
-( discussed in [SSH-ARCH] should be used to avoid attacks by sending) s
-5 294 M
-( terminal control characters.) s
-5 272 M
-(10.2 Ignored Data Message) s
-5 250 M
-( byte SSH_MSG_IGNORE) s
-5 239 M
-( string data) s
-5 217 M
-( All implementations MUST understand \(and ignore\) this message at any) s
-5 206 M
-( time \(after receiving the protocol version\). No implementation is) s
-5 195 M
-( required to send them. This message can be used as an additional) s
-5 184 M
-( protection measure against advanced traffic analysis techniques.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (22,23) 12
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 23 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(10.3 Debug Message) s
-5 668 M
-( byte SSH_MSG_DEBUG) s
-5 657 M
-( boolean always_display) s
-5 646 M
-( string message [RFC2279]) s
-5 635 M
-( string language tag [RFC3066]) s
-5 613 M
-( All implementations MUST understand this message, but they are) s
-5 602 M
-( allowed to ignore it. This message is used to pass the other side) s
-5 591 M
-( information that may help debugging. If always_display is TRUE, the) s
-5 580 M
-( message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed) s
-5 569 M
-( unless debugging information has been explicitly requested by the) s
-5 558 M
-( user.) s
-5 525 M
-( The message doesn't need to contain a newline. It is, however,) s
-5 514 M
-( allowed to consist of multiple lines separated by CRLF \(Carriage) s
-5 503 M
-( Return - Line Feed\) pairs.) s
-5 470 M
-( If the message string is displayed, terminal control character) s
-5 459 M
-( filtering discussed in [SSH-ARCH] should be used to avoid attacks by) s
-5 448 M
-( sending terminal control characters.) s
-5 426 M
-(10.4 Reserved Messages) s
-5 404 M
-( An implementation MUST respond to all unrecognized messages with an) s
-5 393 M
-( SSH_MSG_UNIMPLEMENTED message in the order in which the messages were) s
-5 382 M
-( received. Such messages MUST be otherwise ignored. Later protocol) s
-5 371 M
-( versions may define other meanings for these message types.) s
-5 349 M
-( byte SSH_MSG_UNIMPLEMENTED) s
-5 338 M
-( uint32 packet sequence number of rejected message) s
-5 305 M
-(11. Summary of Message Numbers) s
-5 283 M
-( The following message numbers have been defined in this protocol:) s
-5 261 M
-( #define SSH_MSG_DISCONNECT 1) s
-5 250 M
-( #define SSH_MSG_IGNORE 2) s
-5 239 M
-( #define SSH_MSG_UNIMPLEMENTED 3) s
-5 228 M
-( #define SSH_MSG_DEBUG 4) s
-5 217 M
-( #define SSH_MSG_SERVICE_REQUEST 5) s
-5 206 M
-( #define SSH_MSG_SERVICE_ACCEPT 6) s
-5 184 M
-( #define SSH_MSG_KEXINIT 20) s
-5 173 M
-( #define SSH_MSG_NEWKEYS 21) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 24 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( /* Numbers 30-49 used for kex packets.) s
-5 679 M
-( Different kex methods may reuse message numbers in) s
-5 668 M
-( this range. */) s
-5 646 M
-( #define SSH_MSG_KEXDH_INIT 30) s
-5 635 M
-( #define SSH_MSG_KEXDH_REPLY 31) s
-5 602 M
-(12. IANA Considerations) s
-5 580 M
-( This document is part of a set, the IANA considerations for the SSH) s
-5 569 M
-( protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],) s
-5 558 M
-( [SSH-CONNECT] are detailed in [SSH-NUMBERS].) s
-5 536 M
-(13. Security Considerations) s
-5 514 M
-( This protocol provides a secure encrypted channel over an insecure) s
-5 503 M
-( network. It performs server host authentication, key exchange,) s
-5 492 M
-( encryption, and integrity protection. It also derives a unique) s
-5 481 M
-( session id that may be used by higher-level protocols.) s
-5 459 M
-( Full security considerations for this protocol are provided in) s
-5 448 M
-( Section 8 of [SSH-ARCH]) s
-5 426 M
-(14. Intellectual Property) s
-5 404 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 393 M
-( intellectual property or other rights that might be claimed to) s
-5 382 M
-( pertain to the implementation or use of the technology described in) s
-5 371 M
-( this document or the extent to which any license under such rights) s
-5 360 M
-( might or might not be available; neither does it represent that it) s
-5 349 M
-( has made any effort to identify any such rights. Information on the) s
-5 338 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 327 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 316 M
-( claims of rights made available for publication and any assurances of) s
-5 305 M
-( licenses to be made available, or the result of an attempt made to) s
-5 294 M
-( obtain a general license or permission for the use of such) s
-5 283 M
-( proprietary rights by implementers or users of this specification can) s
-5 272 M
-( be obtained from the IETF Secretariat.) s
-5 250 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 239 M
-( regard to some or all of the specification contained in this) s
-5 228 M
-( document. For more information consult the online list of claimed) s
-5 217 M
-( rights.) s
-5 195 M
-(15. Additional Information) s
-5 173 M
-( The current document editor is: [email protected]. Comments on) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (24,25) 13
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 25 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( this internet draft should be sent to the IETF SECSH working group,) s
-5 679 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 657 M
-(Normative) s
-5 635 M
-( [SSH-ARCH]) s
-5 624 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 613 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 591 M
-( [SSH-TRANS]) s
-5 580 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 569 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 547 M
-( [SSH-USERAUTH]) s
-5 536 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 525 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 503 M
-( [SSH-CONNECT]) s
-5 492 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 481 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 459 M
-( [SSH-NUMBERS]) s
-5 448 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 437 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 426 M
-( 2003.) s
-5 404 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 393 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 371 M
-(Informative) s
-5 349 M
-( [FIPS-186]) s
-5 338 M
-( Federal Information Processing Standards Publication,) s
-5 327 M
-( "FIPS PUB 186, Digital Signature Standard", May 1994.) s
-5 305 M
-( [FIPS-197]) s
-5 294 M
-( NIST, "FIPS PUB 197 Advanced Encryption Standard \(AES\)",) s
-5 283 M
-( November 2001.) s
-5 261 M
-( [FIPS-46-3]) s
-5 250 M
-( U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption) s
-5 239 M
-( Standard \(DES\)", October 1999.) s
-5 217 M
-( [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet) s
-5 206 M
-( X.509 Public Key Infrastructure Certificate and CRL) s
-5 195 M
-( Profile", RFC 2459, January 1999.) s
-5 173 M
-( [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 26 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( STD 13, RFC 1034, November 1987.) s
-5 668 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 657 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 635 M
-( [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format) s
-5 624 M
-( Specification version 3.3", RFC 1950, May 1996.) s
-5 602 M
-( [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification) s
-5 591 M
-( version 1.3", RFC 1951, May 1996.) s
-5 569 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 558 M
-( 10646", RFC 2279, January 1998.) s
-5 536 M
-( [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:) s
-5 525 M
-( Keyed-Hashing for Message Authentication", RFC 2104,) s
-5 514 M
-( February 1997.) s
-5 492 M
-( [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,) s
-5 481 M
-( May 1997.) s
-5 459 M
-( [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,) s
-5 448 M
-( "OpenPGP Message Format", RFC 2440, November 1998.) s
-5 426 M
-( [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,) s
-5 415 M
-( B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,) s
-5 404 M
-( September 1999.) s
-5 382 M
-( [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential \(MODP\)) s
-5 371 M
-( Diffie-Hellman groups for Internet Key Exchange \(IKE\)",) s
-5 360 M
-( RFC 3526, May 2003.) s
-5 338 M
-( [SCHNEIER]) s
-5 327 M
-( Schneier, B., "Applied Cryptography Second Edition:) s
-5 316 M
-( protocols algorithms and source in code in C", 1996.) s
-5 294 M
-( [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A) s
-5 283 M
-( 128-Bit Block Cipher, 1st Edition", March 1999.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (26,27) 14
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 27 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 481 M
-(Appendix A. Contibutors) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 28 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2003\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (28,29) 15
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 29 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Transport Layer Protocol Oct 2003) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-showpage
-PStoPSsaved restore
-%%Trailer
-%%Pages: 29
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt b/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
deleted file mode 100644
index 9073ea52b2..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-transport-17.txt
+++ /dev/null
@@ -1,1624 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 31, 2004 D. Moffat, Editor, Ed.
- Sun Microsystems, Inc
- Oct 2003
-
-
- SSH Transport Layer Protocol
- draft-ietf-secsh-transport-17.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 31, 2004.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network.
-
- This document describes the SSH transport layer protocol which
- typically runs on top of TCP/IP. The protocol can be used as a basis
- for a number of secure network services. It provides strong
- encryption, server authentication, and integrity protection. It may
- also provide compression.
-
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 1]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- all negotiated.
-
- This document also describes the Diffie-Hellman key exchange method
- and the minimal set of algorithms that are needed to implement the
- SSH transport layer protocol.
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 4. Connection Setup . . . . . . . . . . . . . . . . . . . . . . 3
- 4.1 Use over TCP/IP . . . . . . . . . . . . . . . . . . . . . . 4
- 4.2 Protocol Version Exchange . . . . . . . . . . . . . . . . . 4
- 4.3 Compatibility With Old SSH Versions . . . . . . . . . . . . 4
- 4.3.1 Old Client, New Server . . . . . . . . . . . . . . . . . . . 5
- 4.3.2 New Client, Old Server . . . . . . . . . . . . . . . . . . . 5
- 5. Binary Packet Protocol . . . . . . . . . . . . . . . . . . . 5
- 5.1 Maximum Packet Length . . . . . . . . . . . . . . . . . . . 6
- 5.2 Compression . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.3 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 7
- 5.4 Data Integrity . . . . . . . . . . . . . . . . . . . . . . . 9
- 5.5 Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 10
- 5.6 Public Key Algorithms . . . . . . . . . . . . . . . . . . . 11
- 6. Key Exchange . . . . . . . . . . . . . . . . . . . . . . . . 13
- 6.1 Algorithm Negotiation . . . . . . . . . . . . . . . . . . . 13
- 6.2 Output from Key Exchange . . . . . . . . . . . . . . . . . . 16
- 6.3 Taking Keys Into Use . . . . . . . . . . . . . . . . . . . . 17
- 7. Diffie-Hellman Key Exchange . . . . . . . . . . . . . . . . 18
- 7.1 diffie-hellman-group1-sha1 . . . . . . . . . . . . . . . . . 19
- 8. Key Re-Exchange . . . . . . . . . . . . . . . . . . . . . . 20
- 9. Service Request . . . . . . . . . . . . . . . . . . . . . . 21
- 10. Additional Messages . . . . . . . . . . . . . . . . . . . . 21
- 10.1 Disconnection Message . . . . . . . . . . . . . . . . . . . 22
- 10.2 Ignored Data Message . . . . . . . . . . . . . . . . . . . . 22
- 10.3 Debug Message . . . . . . . . . . . . . . . . . . . . . . . 23
- 10.4 Reserved Messages . . . . . . . . . . . . . . . . . . . . . 23
- 11. Summary of Message Numbers . . . . . . . . . . . . . . . . . 23
- 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . 24
- 13. Security Considerations . . . . . . . . . . . . . . . . . . 24
- 14. Intellectual Property . . . . . . . . . . . . . . . . . . . 24
- 15. Additional Information . . . . . . . . . . . . . . . . . . . 24
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 26
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 25
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 25
- A. Contibutors . . . . . . . . . . . . . . . . . . . . . . . . 27
- Intellectual Property and Copyright Statements . . . . . . . 28
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 2]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH transport layer is a secure low level transport protocol. It
- provides strong encryption, cryptographic host authentication, and
- integrity protection.
-
- Authentication in this protocol level is host-based; this protocol
- does not perform user authentication. A higher level protocol for
- user authentication can be designed on top of this protocol.
-
- The protocol has been designed to be simple, flexible, to allow
- parameter negotiation, and to minimize the number of round-trips.
- Key exchange method, public key algorithm, symmetric encryption
- algorithm, message authentication algorithm, and hash algorithm are
- all negotiated. It is expected that in most environments, only 2
- round-trips will be needed for full key exchange, server
- authentication, service request, and acceptance notification of
- service request. The worst case is 3 round-trips.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119].
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH].
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-4. Connection Setup
-
- SSH works over any 8-bit clean, binary-transparent transport. The
- underlying transport SHOULD protect against transmission errors as
- such errors cause the SSH connection to terminate.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 3]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The client initiates the connection.
-
-4.1 Use over TCP/IP
-
- When used over TCP/IP, the server normally listens for connections on
- port 22. This port number has been registered with the IANA, and has
- been officially assigned for SSH.
-
-4.2 Protocol Version Exchange
-
- When the connection has been established, both sides MUST send an
- identification string of the form "SSH-protoversion-softwareversion
- comments", followed by carriage return and newline characters (ASCII
- 13 and 10, respectively). Both sides MUST be able to process
- identification strings without carriage return character. No null
- character is sent. The maximum length of the string is 255
- characters, including the carriage return and newline.
-
- The part of the identification string preceding carriage return and
- newline is used in the Diffie-Hellman key exchange (see Section
- Section 7).
-
- The server MAY send other lines of data before sending the version
- string. Each line SHOULD be terminated by a carriage return and
- newline. Such lines MUST NOT begin with "SSH-", and SHOULD be
- encoded in ISO-10646 UTF-8 [RFC2279] (language is not specified).
- Clients MUST be able to process such lines; they MAY be silently
- ignored, or MAY be displayed to the client user; if they are
- displayed, control character filtering discussed in [SSH-ARCH] SHOULD
- be used. The primary use of this feature is to allow TCP-wrappers to
- display an error message before disconnecting.
-
- Version strings MUST consist of printable US-ASCII characters, not
- including whitespaces or a minus sign (-). The version string is
- primarily used to trigger compatibility extensions and to indicate
- the capabilities of an implementation. The comment string should
- contain additional information that might be useful in solving user
- problems.
-
- The protocol version described in this document is 2.0.
-
- Key exchange will begin immediately after sending this identifier.
- All packets following the identification string SHALL use the binary
- packet protocol, to be described below.
-
-4.3 Compatibility With Old SSH Versions
-
- During the transition period, it is important to be able to work in a
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 4]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- way that is compatible with the installed SSH clients and servers
- that use an older version of the protocol. Information in this
- section is only relevant for implementations supporting compatibility
- with SSH versions 1.x. There is no standards track or informational
- draft available that defines the SSH 1.x protocol. The only known
- documentation of the 1.x protocol is contained in README files that
- are shipped along with the source code.
-
-4.3.1 Old Client, New Server
-
- Server implementations MAY support a configurable "compatibility"
- flag that enables compatibility with old versions. When this flag is
- on, the server SHOULD identify its protocol version as "1.99".
- Clients using protocol 2.0 MUST be able to identify this as identical
- to "2.0". In this mode the server SHOULD NOT send the carriage
- return character (ASCII 13) after the version identification string.
-
- In the compatibility mode the server SHOULD NOT send any further data
- after its initialization string until it has received an
- identification string from the client. The server can then determine
- whether the client is using an old protocol, and can revert to the
- old protocol if required. In the compatibility mode, the server MUST
- NOT send additional data before the version string.
-
- When compatibility with old clients is not needed, the server MAY
- send its initial key exchange data immediately after the
- identification string.
-
-4.3.2 New Client, Old Server
-
- Since the new client MAY immediately send additional data after its
- identification string (before receiving server's identification), the
- old protocol may already have been corrupted when the client learns
- that the server is old. When this happens, the client SHOULD close
- the connection to the server, and reconnect using the old protocol.
-
-5. Binary Packet Protocol
-
- Each packet is in the following format:
-
- uint32 packet_length
- byte padding_length
- byte[n1] payload; n1 = packet_length - padding_length - 1
- byte[n2] random padding; n2 = padding_length
- byte[m] mac (message authentication code); m = mac_length
-
- packet_length
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 5]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The length of the packet (bytes), not including MAC or the
- packet_length field itself.
-
- padding_length
- Length of padding (bytes).
-
- payload
- The useful contents of the packet. If compression has been
- negotiated, this field is compressed. Initially, compression
- MUST be "none".
-
- random padding
- Arbitrary-length padding, such that the total length of
- (packet_length || padding_length || payload || padding) is a
- multiple of the cipher block size or 8, whichever is larger.
- There MUST be at least four bytes of padding. The padding
- SHOULD consist of random bytes. The maximum amount of padding
- is 255 bytes.
-
- mac
- Message authentication code. If message authentication has
- been negotiated, this field contains the MAC bytes. Initially,
- the MAC algorithm MUST be "none".
-
-
- Note that length of the concatenation of packet length, padding
- length, payload, and padding MUST be a multiple of the cipher block
- size or 8, whichever is larger. This constraint MUST be enforced
- even when using stream ciphers. Note that the packet length field is
- also encrypted, and processing it requires special care when sending
- or receiving packets.
-
- The minimum size of a packet is 16 (or the cipher block size,
- whichever is larger) bytes (plus MAC); implementations SHOULD decrypt
- the length after receiving the first 8 (or cipher block size,
- whichever is larger) bytes of a packet.
-
-5.1 Maximum Packet Length
-
- All implementations MUST be able to process packets with uncompressed
- payload length of 32768 bytes or less and total packet size of 35000
- bytes or less (including length, padding length, payload, padding,
- and MAC.). The maximum of 35000 bytes is an arbitrary chosen value
- larger than uncompressed size. Implementations SHOULD support longer
- packets, where they might be needed, e.g. if an implementation wants
- to send a very large number of certificates. Such packets MAY be
- sent if the version string indicates that the other party is able to
- process them. However, implementations SHOULD check that the packet
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 6]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- length is reasonable for the implementation to avoid
- denial-of-service and/or buffer overflow attacks.
-
-5.2 Compression
-
- If compression has been negotiated, the payload field (and only it)
- will be compressed using the negotiated algorithm. The length field
- and MAC will be computed from the compressed payload. Encryption will
- be done after compression.
-
- Compression MAY be stateful, depending on the method. Compression
- MUST be independent for each direction, and implementations MUST
- allow independently choosing the algorithm for each direction.
-
- The following compression methods are currently defined:
-
- none REQUIRED no compression
- zlib OPTIONAL ZLIB (LZ77) compression
-
- The "zlib" compression is described in [RFC1950] and in [RFC1951].
- The compression context is initialized after each key exchange, and
- is passed from one packet to the next with only a partial flush being
- performed at the end of each packet. A partial flush means that the
- current compressed block is ended and all data will be output. If the
- current block is not a stored block, one or more empty blocks are
- added after the current block to ensure that there are at least 8
- bits counting from the start of the end-of-block code of the current
- block to the end of the packet payload.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.3 Encryption
-
- An encryption algorithm and a key will be negotiated during the key
- exchange. When encryption is in effect, the packet length, padding
- length, payload and padding fields of each packet MUST be encrypted
- with the given algorithm.
-
- The encrypted data in all packets sent in one direction SHOULD be
- considered a single data stream. For example, initialization vectors
- SHOULD be passed from the end of one packet to the beginning of the
- next packet. All ciphers SHOULD use keys with an effective key length
- of 128 bits or more.
-
- The ciphers in each direction MUST run independently of each other,
- and implementations MUST allow independently choosing the algorithm
- for each direction (if multiple algorithms are allowed by local
- policy).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 7]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The following ciphers are currently defined:
-
- 3des-cbc REQUIRED three-key 3DES in CBC mode
- blowfish-cbc OPTIONALi Blowfish in CBC mode
- twofish256-cbc OPTIONAL Twofish in CBC mode,
- with 256-bit key
- twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
- is being retained for
- historical reasons)
- twofish192-cbc OPTIONAL Twofish with 192-bit key
- twofish128-cbc OPTIONAL Twofish with 128-bit key
- aes256-cbc OPTIONAL AES (Rijndael) in CBC mode,
- with 256-bit key
- aes192-cbc OPTIONAL AES with 192-bit key
- aes128-cbc RECOMMENDED AES with 128-bit key
- serpent256-cbc OPTIONAL Serpent in CBC mode, with
- 256-bit key
- serpent192-cbc OPTIONAL Serpent with 192-bit key
- serpent128-cbc OPTIONAL Serpent with 128-bit key
- arcfour OPTIONAL the ARCFOUR stream cipher
- idea-cbc OPTIONAL IDEA in CBC mode
- cast128-cbc OPTIONAL CAST-128 in CBC mode
- none OPTIONAL no encryption; NOT RECOMMENDED
-
- The "3des-cbc" cipher is three-key triple-DES
- (encrypt-decrypt-encrypt), where the first 8 bytes of the key are
- used for the first encryption, the next 8 bytes for the decryption,
- and the following 8 bytes for the final encryption. This requires 24
- bytes of key data (of which 168 bits are actually used). To
- implement CBC mode, outer chaining MUST be used (i.e., there is only
- one initialization vector). This is a block cipher with 8 byte
- blocks. This algorithm is defined in [FIPS-46-3]
-
- The "blowfish-cbc" cipher is Blowfish in CBC mode, with 128 bit keys
- [SCHNEIER]. This is a block cipher with 8 byte blocks.
-
- The "twofish-cbc" or "twofish256-cbc" cipher is Twofish in CBC mode,
- with 256 bit keys as described [TWOFISH]. This is a block cipher with
- 16 byte blocks.
-
- The "twofish192-cbc" cipher. Same as above but with 192-bit key.
-
- The "twofish128-cbc" cipher. Same as above but with 128-bit key.
-
- The "aes256-cbc" cipher is AES (Advanced Encryption Standard)
- [FIPS-197], formerly Rijndael, in CBC mode. This version uses 256-bit
- key.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 8]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "aes192-cbc" cipher. Same as above but with 192-bit key.
-
- The "aes128-cbc" cipher. Same as above but with 128-bit key.
-
- The "serpent256-cbc" cipher in CBC mode, with 256-bit key as
- described in the Serpent AES submission.
-
- The "serpent192-cbc" cipher. Same as above but with 192-bit key.
-
- The "serpent128-cbc" cipher. Same as above but with 128-bit key.
-
- The "arcfour" is the Arcfour stream cipher with 128 bit keys. The
- Arcfour cipher is believed to be compatible with the RC4 cipher
- [SCHNEIER]. RC4 is a registered trademark of RSA Data Security Inc.
- Arcfour (and RC4) has problems with weak keys, and should be used
- with caution.
-
- The "idea-cbc" cipher is the IDEA cipher in CBC mode [SCHNEIER].
-
- The "cast128-cbc" cipher is the CAST-128 cipher in CBC mode
- [RFC2144].
-
- The "none" algorithm specifies that no encryption is to be done.
- Note that this method provides no confidentiality protection, and it
- is not recommended. Some functionality (e.g. password
- authentication) may be disabled for security reasons if this cipher
- is chosen.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.4 Data Integrity
-
- Data integrity is protected by including with each packet a message
- authentication code (MAC) that is computed from a shared secret,
- packet sequence number, and the contents of the packet.
-
- The message authentication algorithm and key are negotiated during
- key exchange. Initially, no MAC will be in effect, and its length
- MUST be zero. After key exchange, the selected MAC will be computed
- before encryption from the concatenation of packet data:
-
- mac = MAC(key, sequence_number || unencrypted_packet)
-
- where unencrypted_packet is the entire packet without MAC (the length
- fields, payload and padding), and sequence_number is an implicit
- packet sequence number represented as uint32. The sequence number is
- initialized to zero for the first packet, and is incremented after
- every packet (regardless of whether encryption or MAC is in use). It
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 9]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- is never reset, even if keys/algorithms are renegotiated later. It
- wraps around to zero after every 2^32 packets. The packet sequence
- number itself is not included in the packet sent over the wire.
-
- The MAC algorithms for each direction MUST run independently, and
- implementations MUST allow choosing the algorithm independently for
- both directions.
-
- The MAC bytes resulting from the MAC algorithm MUST be transmitted
- without encryption as the last part of the packet. The number of MAC
- bytes depends on the algorithm chosen.
-
- The following MAC algorithms are currently defined:
-
- hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
- length = 20)
- hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
- length = 12, key length = 20)
- hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
- length = 16)
- hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
- length = 12, key length = 16)
- none OPTIONAL no MAC; NOT RECOMMENDED
-
- Figure 1
-
- The "hmac-*" algorithms are described in [RFC2104] The "*-n" MACs use
- only the first n bits of the resulting value.
-
- The hash algorithms are described in [SCHNEIER].
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-5.5 Key Exchange Methods
-
- The key exchange method specifies how one-time session keys are
- generated for encryption and for authentication, and how the server
- authentication is done.
-
- Only one REQUIRED key exchange method has been defined:
-
- diffie-hellman-group1-sha1 REQUIRED
-
- This method is described later in this document.
-
- Additional methods may be defined as specified in [SSH-ARCH].
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 10]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-5.6 Public Key Algorithms
-
- This protocol has been designed to be able to operate with almost any
- public key format, encoding, and algorithm (signature and/or
- encryption).
-
- There are several aspects that define a public key type:
- o Key format: how is the key encoded and how are certificates
- represented. The key blobs in this protocol MAY contain
- certificates in addition to keys.
- o Signature and/or encryption algorithms. Some key types may not
- support both signing and encryption. Key usage may also be
- restricted by policy statements in e.g. certificates. In this
- case, different key types SHOULD be defined for the different
- policy alternatives.
- o Encoding of signatures and/or encrypted data. This includes but is
- not limited to padding, byte order, and data formats.
-
- The following public key and/or certificate formats are currently defined:
-
- ssh-dss REQUIRED sign Raw DSS Key
- ssh-rsa RECOMMENDED sign Raw RSA Key
- x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
- x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
- spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
- spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
- pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
- pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-
- Additional key types may be defined as specified in [SSH-ARCH].
-
- The key type MUST always be explicitly known (from algorithm
- negotiation or some other source). It is not normally included in
- the key blob.
-
- Certificates and public keys are encoded as follows:
-
- string certificate or public key format identifier
- byte[n] key/certificate data
-
- The certificate part may have be a zero length string, but a public
- key is required. This is the public key that will be used for
- authentication; the certificate sequence contained in the certificate
- blob can be used to provide authorization.
-
- Public key / certifcate formats that do not explicitly specify a
- signature format identifier MUST use the public key / certificate
- format identifier as the signature identifier.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 11]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Signatures are encoded as follows:
- string signature format identifier (as specified by the
- public key / cert format)
- byte[n] signature blob in format specific encoding.
-
-
- The "ssh-dss" key format has the following specific encoding:
-
- string "ssh-dss"
- mpint p
- mpint q
- mpint g
- mpint y
-
- Here the p, q, g, and y parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to the
- Digital Signature Standard [FIPS-186] using the SHA-1 hash. A
- description can also be found in [SCHNEIER].
-
- The resulting signature is encoded as follows:
-
- string "ssh-dss"
- string dss_signature_blob
-
- dss_signature_blob is encoded as a string containing r followed by s
- (which are 160 bits long integers, without lengths or padding,
- unsigned and in network byte order).
-
- The "ssh-rsa" key format has the following specific encoding:
-
- string "ssh-rsa"
- mpint e
- mpint n
-
- Here the e and n parameters form the signature key blob.
-
- Signing and verifying using this key format is done according to
- [SCHNEIER] and [PKCS1] using the SHA-1 hash.
-
- The resulting signature is encoded as follows:
-
- string "ssh-rsa"
- string rsa_signature_blob
-
- rsa_signature_blob is encoded as a string containing s (which is an
- integer, without lengths or padding, unsigned and in network byte
- order).
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 12]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- The "spki-sign-rsa" method indicates that the certificate blob
- contains a sequence of SPKI certificates. The format of SPKI
- certificates is described in [RFC2693]. This method indicates that
- the key (or one of the keys in the certificate) is an RSA-key.
-
- The "spki-sign-dss". As above, but indicates that the key (or one of
- the keys in the certificate) is a DSS-key.
-
- The "pgp-sign-rsa" method indicates the certificates, the public key,
- and the signature are in OpenPGP compatible binary format
- ([RFC2440]). This method indicates that the key is an RSA-key.
-
- The "pgp-sign-dss". As above, but indicates that the key is a
- DSS-key.
-
-6. Key Exchange
-
- Key exchange begins by each side sending lists of supported
- algorithms. Each side has a preferred algorithm in each category, and
- it is assumed that most implementations at any given time will use
- the same preferred algorithm. Each side MAY guess which algorithm
- the other side is using, and MAY send an initial key exchange packet
- according to the algorithm if appropriate for the preferred method.
-
- Guess is considered wrong, if:
- o the kex algorithm and/or the host key algorithm is guessed wrong
- (server and client have different preferred algorithm), or
- o if any of the other algorithms cannot be agreed upon (the
- procedure is defined below in Section Section 6.1).
-
- Otherwise, the guess is considered to be right and the optimistically
- sent packet MUST be handled as the first key exchange packet.
-
- However, if the guess was wrong, and a packet was optimistically sent
- by one or both parties, such packets MUST be ignored (even if the
- error in the guess would not affect the contents of the initial
- packet(s)), and the appropriate side MUST send the correct initial
- packet.
-
- Server authentication in the key exchange MAY be implicit. After a
- key exchange with implicit server authentication, the client MUST
- wait for response to its service request message before sending any
- further data.
-
-6.1 Algorithm Negotiation
-
- Key exchange begins by each side sending the following packet:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 13]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXINIT
- byte[16] cookie (random bytes)
- string kex_algorithms
- string server_host_key_algorithms
- string encryption_algorithms_client_to_server
- string encryption_algorithms_server_to_client
- string mac_algorithms_client_to_server
- string mac_algorithms_server_to_client
- string compression_algorithms_client_to_server
- string compression_algorithms_server_to_client
- string languages_client_to_server
- string languages_server_to_client
- boolean first_kex_packet_follows
- uint32 0 (reserved for future extension)
-
- Each of the algorithm strings MUST be a comma-separated list of
- algorithm names (see ''Algorithm Naming'' in [SSH-ARCH]). Each
- supported (allowed) algorithm MUST be listed in order of preference.
-
- The first algorithm in each list MUST be the preferred (guessed)
- algorithm. Each string MUST contain at least one algorithm name.
-
-
- cookie
- The cookie MUST be a random value generated by the sender. Its
- purpose is to make it impossible for either side to fully
- determine the keys and the session identifier.
-
- kex_algorithms
- Key exchange algorithms were defined above. The first
- algorithm MUST be the preferred (and guessed) algorithm. If
- both sides make the same guess, that algorithm MUST be used.
- Otherwise, the following algorithm MUST be used to choose a key
- exchange method: iterate over client's kex algorithms, one at a
- time. Choose the first algorithm that satisfies the following
- conditions:
- + the server also supports the algorithm,
- + if the algorithm requires an encryption-capable host key,
- there is an encryption-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client, and
- + if the algorithm requires a signature-capable host key,
- there is a signature-capable algorithm on the server's
- server_host_key_algorithms that is also supported by the
- client.
- + If no algorithm satisfying all these conditions can be
- found, the connection fails, and both sides MUST disconnect.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 14]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- server_host_key_algorithms
- List of the algorithms supported for the server host key. The
- server lists the algorithms for which it has host keys; the
- client lists the algorithms that it is willing to accept.
- (There MAY be multiple host keys for a host, possibly with
- different algorithms.)
-
- Some host keys may not support both signatures and encryption
- (this can be determined from the algorithm), and thus not all
- host keys are valid for all key exchange methods.
-
- Algorithm selection depends on whether the chosen key exchange
- algorithm requires a signature or encryption capable host key.
- It MUST be possible to determine this from the public key
- algorithm name. The first algorithm on the client's list that
- satisfies the requirements and is also supported by the server
- MUST be chosen. If there is no such algorithm, both sides MUST
- disconnect.
-
- encryption_algorithms
- Lists the acceptable symmetric encryption algorithms in order
- of preference. The chosen encryption algorithm to each
- direction MUST be the first algorithm on the client's list
- that is also on the server's list. If there is no such
- algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The defined algorithm names are listed in Section
- Section 5.3.
-
- mac_algorithms
- Lists the acceptable MAC algorithms in order of preference.
- The chosen MAC algorithm MUST be the first algorithm on the
- client's list that is also on the server's list. If there is
- no such algorithm, both sides MUST disconnect.
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The MAC algorithm names are listed in Section
- Figure 1.
-
- compression_algorithms
- Lists the acceptable compression algorithms in order of
- preference. The chosen compression algorithm MUST be the first
- algorithm on the client's list that is also on the server's
- list. If there is no such algorithm, both sides MUST
- disconnect.
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 15]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- Note that "none" must be explicitly listed if it is to be
- acceptable. The compression algorithm names are listed in
- Section Section 5.2.
-
- languages
- This is a comma-separated list of language tags in order of
- preference [RFC3066]. Both parties MAY ignore this list. If
- there are no language preferences, this list SHOULD be empty.
- Language tags SHOULD NOT be present unless they are known to be
- needed by the sending party.
-
- first_kex_packet_follows
- Indicates whether a guessed key exchange packet follows. If a
- guessed packet will be sent, this MUST be TRUE. If no guessed
- packet will be sent, this MUST be FALSE.
-
- After receiving the SSH_MSG_KEXINIT packet from the other side,
- each party will know whether their guess was right. If the
- other party's guess was wrong, and this field was TRUE, the
- next packet MUST be silently ignored, and both sides MUST then
- act as determined by the negotiated key exchange method. If
- the guess was right, key exchange MUST continue using the
- guessed packet.
-
- After the KEXINIT packet exchange, the key exchange algorithm is run.
- It may involve several packet exchanges, as specified by the key
- exchange method.
-
-6.2 Output from Key Exchange
-
- The key exchange produces two values: a shared secret K, and an
- exchange hash H. Encryption and authentication keys are derived from
- these. The exchange hash H from the first key exchange is
- additionally used as the session identifier, which is a unique
- identifier for this connection. It is used by authentication methods
- as a part of the data that is signed as a proof of possession of a
- private key. Once computed, the session identifier is not changed,
- even if keys are later re-exchanged.
-
-
- Each key exchange method specifies a hash function that is used in
- the key exchange. The same hash algorithm MUST be used in key
- derivation. Here, we'll call it HASH.
-
-
- Encryption keys MUST be computed as HASH of a known value and K as
- follows:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 16]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- o Initial IV client to server: HASH(K || H || "A" || session_id)
- (Here K is encoded as mpint and "A" as byte and session_id as raw
- data."A" means the single character A, ASCII 65).
- o Initial IV server to client: HASH(K || H || "B" || session_id)
- o Encryption key client to server: HASH(K || H || "C" || session_id)
- o Encryption key server to client: HASH(K || H || "D" || session_id)
- o Integrity key client to server: HASH(K || H || "E" || session_id)
- o Integrity key server to client: HASH(K || H || "F" || session_id)
-
- Key data MUST be taken from the beginning of the hash output. 128
- bits (16 bytes) MUST be used for algorithms with variable-length
- keys. The only variable key length algorithm defined in this document
- is arcfour). For other algorithms, as many bytes as are needed are
- taken from the beginning of the hash value. If the key length needed
- is longer than the output of the HASH, the key is extended by
- computing HASH of the concatenation of K and H and the entire key so
- far, and appending the resulting bytes (as many as HASH generates) to
- the key. This process is repeated until enough key material is
- available; the key is taken from the beginning of this value. In
- other words:
-
- K1 = HASH(K || H || X || session_id) (X is e.g. "A")
- K2 = HASH(K || H || K1)
- K3 = HASH(K || H || K1 || K2)
- ...
- key = K1 || K2 || K3 || ...
-
- This process will lose entropy if the amount of entropy in K is
- larger than the internal state size of HASH.
-
-6.3 Taking Keys Into Use
-
- Key exchange ends by each side sending an SSH_MSG_NEWKEYS message.
- This message is sent with the old keys and algorithms. All messages
- sent after this message MUST use the new keys and algorithms.
-
-
- When this message is received, the new keys and algorithms MUST be
- taken into use for receiving.
-
-
- This message is the only valid message after key exchange, in
- addition to SSH_MSG_DEBUG, SSH_MSG_DISCONNECT and SSH_MSG_IGNORE
- messages. The purpose of this message is to ensure that a party is
- able to respond with a disconnect message that the other party can
- understand if something goes wrong with the key exchange.
- Implementations MUST NOT accept any other messages after key exchange
- before receiving SSH_MSG_NEWKEYS.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 17]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_NEWKEYS
-
-
-7. Diffie-Hellman Key Exchange
-
- The Diffie-Hellman key exchange provides a shared secret that can not
- be determined by either party alone. The key exchange is combined
- with a signature with the host key to provide host authentication.
-
-
- In the following description (C is the client, S is the server; p is
- a large safe prime, g is a generator for a subgroup of GF(p), and q
- is the order of the subgroup; V_S is S's version string; V_C is C's
- version string; K_S is S's public host key; I_C is C's KEXINIT
- message and I_S S's KEXINIT message which have been exchanged before
- this part begins):
-
-
- 1. C generates a random number x (1 < x < q) and computes e = g^x
- mod p. C sends "e" to S.
-
- 2. S generates a random number y (0 < y < q) and computes f = g^y
- mod p. S receives "e". It computes K = e^y mod p, H = hash(V_C
- || V_S || I_C || I_S || K_S || e || f || K) (these elements are
- encoded according to their types; see below), and signature s on
- H with its private host key. S sends "K_S || f || s" to C. The
- signing operation may involve a second hashing operation.
-
- 3. C verifies that K_S really is the host key for S (e.g. using
- certificates or a local database). C is also allowed to accept
- the key without verification; however, doing so will render the
- protocol insecure against active attacks (but may be desirable
- for practical reasons in the short term in many environments). C
- then computes K = f^x mod p, H = hash(V_C || V_S || I_C || I_S ||
- K_S || e || f || K), and verifies the signature s on H.
-
- Either side MUST NOT send or accept e or f values that are not in the
- range [1, p-1]. If this condition is violated, the key exchange
- fails.
-
-
- This is implemented with the following messages. The hash algorithm
- for computing the exchange hash is defined by the method name, and is
- called HASH. The public key algorithm for signing is negotiated with
- the KEXINIT messages.
-
- First, the client sends the following:
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 18]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- byte SSH_MSG_KEXDH_INIT
- mpint e
-
-
- The server responds with the following:
-
- byte SSH_MSG_KEXDH_REPLY
- string server public host key and certificates (K_S)
- mpint f
- string signature of H
-
- The hash H is computed as the HASH hash of the concatenation of the
- following:
-
- string V_C, the client's version string (CR and NL excluded)
- string V_S, the server's version string (CR and NL excluded)
- string I_C, the payload of the client's SSH_MSG_KEXINIT
- string I_S, the payload of the server's SSH_MSG_KEXINIT
- string K_S, the host key
- mpint e, exchange value sent by the client
- mpint f, exchange value sent by the server
- mpint K, the shared secret
-
- This value is called the exchange hash, and it is used to
- authenticate the key exchange. The exchange hash SHOULD be kept
- secret.
-
-
- The signature algorithm MUST be applied over H, not the original
- data. Most signature algorithms include hashing and additional
- padding. For example, "ssh-dss" specifies SHA-1 hashing; in that
- case, the data is first hashed with HASH to compute H, and H is then
- hashed with SHA-1 as part of the signing operation.
-
-7.1 diffie-hellman-group1-sha1
-
- The "diffie-hellman-group1-sha1" method specifies Diffie-Hellman key
- exchange with SHA-1 as HASH, and Oakley group 14 [RFC3526] (2048-bit
- MODP Group). It is included below in hexadecimal and decimal.
-
- The prime p is equal to 2^1024 - 2^960 - 1 + 2^64 * floor( 2^894 Pi +
- 129093 ). Its hexadecimal value is:
-
- FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
- 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
- EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
- E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
- EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 19]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- FFFFFFFF FFFFFFFF.
-
- In decimal, this value is:
-
- 179769313486231590770839156793787453197860296048756011706444
- 423684197180216158519368947833795864925541502180565485980503
- 646440548199239100050792877003355816639229553136239076508735
- 759914822574862575007425302077447712589550957937778424442426
- 617334727629299387668709205606050270810842907692932019128194
- 467627007.
-
- The generator used with this prime is g = 2. The group order q is (p
- - 1) / 2.
-
-8. Key Re-Exchange
-
- Key re-exchange is started by sending an SSH_MSG_KEXINIT packet when
- not already doing a key exchange (as described in Section Section
- 6.1). When this message is received, a party MUST respond with its
- own SSH_MSG_KEXINIT message except when the received SSH_MSG_KEXINIT
- already was a reply. Either party MAY initiate the re-exchange, but
- roles MUST NOT be changed (i.e., the server remains the server, and
- the client remains the client).
-
-
- Key re-exchange is performed using whatever encryption was in effect
- when the exchange was started. Encryption, compression, and MAC
- methods are not changed before a new SSH_MSG_NEWKEYS is sent after
- the key exchange (as in the initial key exchange). Re-exchange is
- processed identically to the initial key exchange, except for the
- session identifier that will remain unchanged. It is permissible to
- change some or all of the algorithms during the re-exchange. Host
- keys can also change. All keys and initialization vectors are
- recomputed after the exchange. Compression and encryption contexts
- are reset.
-
-
- It is recommended that the keys are changed after each gigabyte of
- transmitted data or after each hour of connection time, whichever
- comes sooner. However, since the re-exchange is a public key
- operation, it requires a fair amount of processing power and should
- not be performed too often.
-
-
- More application data may be sent after the SSH_MSG_NEWKEYS packet
- has been sent; key exchange does not affect the protocols that lie
- above the SSH transport layer.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 20]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-9. Service Request
-
- After the key exchange, the client requests a service. The service is
- identified by a name. The format of names and procedures for defining
- new names are defined in [SSH-ARCH].
-
-
- Currently, the following names have been reserved:
-
- ssh-userauth
- ssh-connection
-
- Similar local naming policy is applied to the service names, as is
- applied to the algorithm names; a local service should use the
- "servicename@domain" syntax.
-
- byte SSH_MSG_SERVICE_REQUEST
- string service name
-
- If the server rejects the service request, it SHOULD send an
- appropriate SSH_MSG_DISCONNECT message and MUST disconnect.
-
-
- When the service starts, it may have access to the session identifier
- generated during the key exchange.
-
-
- If the server supports the service (and permits the client to use
- it), it MUST respond with the following:
-
- byte SSH_MSG_SERVICE_ACCEPT
- string service name
-
- Message numbers used by services should be in the area reserved for
- them (see Section 6 in [SSH-ARCH]). The transport level will
- continue to process its own messages.
-
-
- Note that after a key exchange with implicit server authentication,
- the client MUST wait for response to its service request message
- before sending any further data.
-
-10. Additional Messages
-
- Either party may send any of the following messages at any time.
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 21]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.1 Disconnection Message
-
- byte SSH_MSG_DISCONNECT
- uint32 reason code
- string description [RFC2279]
- string language tag [RFC3066]
-
- This message causes immediate termination of the connection. All
- implementations MUST be able to process this message; they SHOULD be
- able to send this message.
-
- The sender MUST NOT send or receive any data after this message, and
- the recipient MUST NOT accept any data after receiving this message.
- The description field gives a more specific explanation in a
- human-readable form. The error code gives the reason in a more
- machine-readable format (suitable for localization), and can have the
- following values:
-
- #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
- #define SSH_DISCONNECT_PROTOCOL_ERROR 2
- #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
- #define SSH_DISCONNECT_RESERVED 4
- #define SSH_DISCONNECT_MAC_ERROR 5
- #define SSH_DISCONNECT_COMPRESSION_ERROR 6
- #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
- #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
- #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
- #define SSH_DISCONNECT_CONNECTION_LOST 10
- #define SSH_DISCONNECT_BY_APPLICATION 11
- #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
- #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
- #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
- #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
-
- If the description string is displayed, control character filtering
- discussed in [SSH-ARCH] should be used to avoid attacks by sending
- terminal control characters.
-
-10.2 Ignored Data Message
-
- byte SSH_MSG_IGNORE
- string data
-
- All implementations MUST understand (and ignore) this message at any
- time (after receiving the protocol version). No implementation is
- required to send them. This message can be used as an additional
- protection measure against advanced traffic analysis techniques.
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 22]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-10.3 Debug Message
-
- byte SSH_MSG_DEBUG
- boolean always_display
- string message [RFC2279]
- string language tag [RFC3066]
-
- All implementations MUST understand this message, but they are
- allowed to ignore it. This message is used to pass the other side
- information that may help debugging. If always_display is TRUE, the
- message SHOULD be displayed. Otherwise, it SHOULD NOT be displayed
- unless debugging information has been explicitly requested by the
- user.
-
-
- The message doesn't need to contain a newline. It is, however,
- allowed to consist of multiple lines separated by CRLF (Carriage
- Return - Line Feed) pairs.
-
-
- If the message string is displayed, terminal control character
- filtering discussed in [SSH-ARCH] should be used to avoid attacks by
- sending terminal control characters.
-
-10.4 Reserved Messages
-
- An implementation MUST respond to all unrecognized messages with an
- SSH_MSG_UNIMPLEMENTED message in the order in which the messages were
- received. Such messages MUST be otherwise ignored. Later protocol
- versions may define other meanings for these message types.
-
- byte SSH_MSG_UNIMPLEMENTED
- uint32 packet sequence number of rejected message
-
-
-11. Summary of Message Numbers
-
- The following message numbers have been defined in this protocol:
-
- #define SSH_MSG_DISCONNECT 1
- #define SSH_MSG_IGNORE 2
- #define SSH_MSG_UNIMPLEMENTED 3
- #define SSH_MSG_DEBUG 4
- #define SSH_MSG_SERVICE_REQUEST 5
- #define SSH_MSG_SERVICE_ACCEPT 6
-
- #define SSH_MSG_KEXINIT 20
- #define SSH_MSG_NEWKEYS 21
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 23]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- /* Numbers 30-49 used for kex packets.
- Different kex methods may reuse message numbers in
- this range. */
-
- #define SSH_MSG_KEXDH_INIT 30
- #define SSH_MSG_KEXDH_REPLY 31
-
-
-12. IANA Considerations
-
- This document is part of a set, the IANA considerations for the SSH
- protocol as defined in [SSH-ARCH], [SSH-TRANS], [SSH-USERAUTH],
- [SSH-CONNECT] are detailed in [SSH-NUMBERS].
-
-13. Security Considerations
-
- This protocol provides a secure encrypted channel over an insecure
- network. It performs server host authentication, key exchange,
- encryption, and integrity protection. It also derives a unique
- session id that may be used by higher-level protocols.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-14. Intellectual Property
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementers or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-15. Additional Information
-
- The current document editor is: [email protected]. Comments on
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 24]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- this internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [FIPS-186]
- Federal Information Processing Standards Publication,
- "FIPS PUB 186, Digital Signature Standard", May 1994.
-
- [FIPS-197]
- NIST, "FIPS PUB 197 Advanced Encryption Standard (AES)",
- November 2001.
-
- [FIPS-46-3]
- U.S. Dept. of Commerce, "FIPS PUB 46-3, Data Encryption
- Standard (DES)", October 1999.
-
- [RFC2459] Housley, R., Ford, W., Polk, T. and D. Solo, "Internet
- X.509 Public Key Infrastructure Certificate and CRL
- Profile", RFC 2459, January 1999.
-
- [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 25]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- STD 13, RFC 1034, November 1987.
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format
- Specification version 3.3", RFC 1950, May 1996.
-
- [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification
- version 1.3", RFC 1951, May 1996.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
- [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
- [RFC2144] Adams, C., "The CAST-128 Encryption Algorithm", RFC 2144,
- May 1997.
-
- [RFC2440] Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,
- "OpenPGP Message Format", RFC 2440, November 1998.
-
- [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas,
- B. and T. Ylonen, "SPKI Certificate Theory", RFC 2693,
- September 1999.
-
- [RFC3526] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP)
- Diffie-Hellman groups for Internet Key Exchange (IKE)",
- RFC 3526, May 2003.
-
- [SCHNEIER]
- Schneier, B., "Applied Cryptography Second Edition:
- protocols algorithms and source in code in C", 1996.
-
- [TWOFISH] Schneier, B., "The Twofish Encryptions Algorithm: A
- 128-Bit Block Cipher, 1st Edition", March 1999.
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 26]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-Appendix A. Contibutors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 27]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 28]
-
-Internet-Draft SSH Transport Layer Protocol Oct 2003
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat, Editor Expires March 31, 2004 [Page 29] \ No newline at end of file
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
deleted file mode 100644
index be5799dbce..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.2.ps
+++ /dev/null
@@ -1,1881 +0,0 @@
-%!PS-Adobe-3.0
-%%BoundingBox: 75 0 595 747
-%%Title: Enscript Output
-%%For: Magnus Thoang
-%%Creator: GNU enscript 1.6.1
-%%CreationDate: Fri Oct 31 13:35:32 2003
-%%Orientation: Portrait
-%%Pages: 8 0
-%%DocumentMedia: A4 595 842 0 () ()
-%%DocumentNeededResources: (atend)
-%%EndComments
-%%BeginProlog
-%%BeginProcSet: PStoPS 1 15
-userdict begin
-[/showpage/erasepage/copypage]{dup where{pop dup load
- type/operatortype eq{1 array cvx dup 0 3 index cvx put
- bind def}{pop}ifelse}{pop}ifelse}forall
-[/letter/legal/executivepage/a4/a4small/b5/com10envelope
- /monarchenvelope/c5envelope/dlenvelope/lettersmall/note
- /folio/quarto/a5]{dup where{dup wcheck{exch{}put}
- {pop{}def}ifelse}{pop}ifelse}forall
-/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}
- {pop def}ifelse}{def}ifelse
-/PStoPSmatrix matrix currentmatrix def
-/PStoPSxform matrix def/PStoPSclip{clippath}def
-/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def
-/initmatrix{matrix defaultmatrix setmatrix}bind def
-/initclip[{matrix currentmatrix PStoPSmatrix setmatrix
- [{currentpoint}stopped{$error/newerror false put{newpath}}
- {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]
- {[/newpath cvx{/moveto cvx}{/lineto cvx}
- {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}
- stopped{$error/errorname get/invalidaccess eq{cleartomark
- $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop
- /initclip dup load dup type dup/operatortype eq{pop exch pop}
- {dup/arraytype eq exch/packedarraytype eq or
- {dup xcheck{exch pop aload pop}{pop cvx}ifelse}
- {pop cvx}ifelse}ifelse
- {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def
-/initgraphics{initmatrix newpath initclip 1 setlinewidth
- 0 setlinecap 0 setlinejoin []0 setdash 0 setgray
- 10 setmiterlimit}bind def
-end
-%%EndProcSet
-%%BeginResource: procset Enscript-Prolog 1.6 1
-%
-% Procedures.
-%
-
-/_S { % save current state
- /_s save def
-} def
-/_R { % restore from saved state
- _s restore
-} def
-
-/S { % showpage protecting gstate
- gsave
- showpage
- grestore
-} bind def
-
-/MF { % fontname newfontname -> - make a new encoded font
- /newfontname exch def
- /fontname exch def
-
- /fontdict fontname findfont def
- /newfont fontdict maxlength dict def
-
- fontdict {
- exch
- dup /FID eq {
- % skip FID pair
- pop pop
- } {
- % copy to the new font dictionary
- exch newfont 3 1 roll put
- } ifelse
- } forall
-
- newfont /FontName newfontname put
-
- % insert only valid encoding vectors
- encoding_vector length 256 eq {
- newfont /Encoding encoding_vector put
- } if
-
- newfontname newfont definefont pop
-} def
-
-/SF { % fontname width height -> - set a new font
- /height exch def
- /width exch def
-
- findfont
- [width 0 0 height 0 0] makefont setfont
-} def
-
-/SUF { % fontname width height -> - set a new user font
- /height exch def
- /width exch def
-
- /F-gs-user-font MF
- /F-gs-user-font width height SF
-} def
-
-/M {moveto} bind def
-/s {show} bind def
-
-/Box { % x y w h -> - define box path
- /d_h exch def /d_w exch def /d_y exch def /d_x exch def
- d_x d_y moveto
- d_w 0 rlineto
- 0 d_h rlineto
- d_w neg 0 rlineto
- closepath
-} def
-
-/bgs { % x y height blskip gray str -> - show string with bg color
- /str exch def
- /gray exch def
- /blskip exch def
- /height exch def
- /y exch def
- /x exch def
-
- gsave
- x y blskip sub str stringwidth pop height Box
- gray setgray
- fill
- grestore
- x y M str s
-} def
-
-% Highlight bars.
-/highlight_bars { % nlines lineheight output_y_margin gray -> -
- gsave
- setgray
- /ymarg exch def
- /lineheight exch def
- /nlines exch def
-
- % This 2 is just a magic number to sync highlight lines to text.
- 0 d_header_y ymarg sub 2 sub translate
-
- /cw d_output_w cols div def
- /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
-
- % for each column
- 0 1 cols 1 sub {
- cw mul /xp exch def
-
- % for each rows
- 0 1 nrows 1 sub {
- /rn exch def
- rn lineheight mul neg /yp exch def
- rn nlines idiv 2 mod 0 eq {
- % Draw highlight bar. 4 is just a magic indentation.
- xp 4 add yp cw 8 sub lineheight neg Box fill
- } if
- } for
- } for
-
- grestore
-} def
-
-% Line highlight bar.
-/line_highlight { % x y width height gray -> -
- gsave
- /gray exch def
- Box gray setgray fill
- grestore
-} def
-
-% Column separator lines.
-/column_lines {
- gsave
- .1 setlinewidth
- 0 d_footer_h translate
- /cw d_output_w cols div def
- 1 1 cols 1 sub {
- cw mul 0 moveto
- 0 d_output_h rlineto stroke
- } for
- grestore
-} def
-
-% Column borders.
-/column_borders {
- gsave
- .1 setlinewidth
- 0 d_footer_h moveto
- 0 d_output_h rlineto
- d_output_w 0 rlineto
- 0 d_output_h neg rlineto
- closepath stroke
- grestore
-} def
-
-% Do the actual underlay drawing
-/draw_underlay {
- ul_style 0 eq {
- ul_str true charpath stroke
- } {
- ul_str show
- } ifelse
-} def
-
-% Underlay
-/underlay { % - -> -
- gsave
- 0 d_page_h translate
- d_page_h neg d_page_w atan rotate
-
- ul_gray setgray
- ul_font setfont
- /dw d_page_h dup mul d_page_w dup mul add sqrt def
- ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
- draw_underlay
- grestore
-} def
-
-/user_underlay { % - -> -
- gsave
- ul_x ul_y translate
- ul_angle rotate
- ul_gray setgray
- ul_font setfont
- 0 0 ul_h_ptsize 2 div sub moveto
- draw_underlay
- grestore
-} def
-
-% Page prefeed
-/page_prefeed { % bool -> -
- statusdict /prefeed known {
- statusdict exch /prefeed exch put
- } {
- pop
- } ifelse
-} def
-
-% Wrapped line markers
-/wrapped_line_mark { % x y charwith charheight type -> -
- /type exch def
- /h exch def
- /w exch def
- /y exch def
- /x exch def
-
- type 2 eq {
- % Black boxes (like TeX does)
- gsave
- 0 setlinewidth
- x w 4 div add y M
- 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
- closepath fill
- grestore
- } {
- type 3 eq {
- % Small arrows
- gsave
- .2 setlinewidth
- x w 2 div add y h 2 div add M
- w 4 div 0 rlineto
- x w 4 div add y lineto stroke
-
- x w 4 div add w 8 div add y h 4 div add M
- x w 4 div add y lineto
- w 4 div h 8 div rlineto stroke
- grestore
- } {
- % do nothing
- } ifelse
- } ifelse
-} def
-
-% EPSF import.
-
-/BeginEPSF {
- /b4_Inc_state save def % Save state for cleanup
- /dict_count countdictstack def % Count objects on dict stack
- /op_count count 1 sub def % Count objects on operand stack
- userdict begin
- /showpage { } def
- 0 setgray 0 setlinecap
- 1 setlinewidth 0 setlinejoin
- 10 setmiterlimit [ ] 0 setdash newpath
- /languagelevel where {
- pop languagelevel
- 1 ne {
- false setstrokeadjust false setoverprint
- } if
- } if
-} bind def
-
-/EndEPSF {
- count op_count sub { pos } repeat % Clean up stacks
- countdictstack dict_count sub { end } repeat
- b4_Inc_state restore
-} bind def
-
-% Check PostScript language level.
-/languagelevel where {
- pop /gs_languagelevel languagelevel def
-} {
- /gs_languagelevel 1 def
-} ifelse
-%%EndResource
-%%BeginResource: procset Enscript-Encoding-88591 1.6 1
-/encoding_vector [
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclam /quotedbl /numbersign
-/dollar /percent /ampersand /quoteright
-/parenleft /parenright /asterisk /plus
-/comma /hyphen /period /slash
-/zero /one /two /three
-/four /five /six /seven
-/eight /nine /colon /semicolon
-/less /equal /greater /question
-/at /A /B /C
-/D /E /F /G
-/H /I /J /K
-/L /M /N /O
-/P /Q /R /S
-/T /U /V /W
-/X /Y /Z /bracketleft
-/backslash /bracketright /asciicircum /underscore
-/quoteleft /a /b /c
-/d /e /f /g
-/h /i /j /k
-/l /m /n /o
-/p /q /r /s
-/t /u /v /w
-/x /y /z /braceleft
-/bar /braceright /tilde /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/.notdef /.notdef /.notdef /.notdef
-/space /exclamdown /cent /sterling
-/currency /yen /brokenbar /section
-/dieresis /copyright /ordfeminine /guillemotleft
-/logicalnot /hyphen /registered /macron
-/degree /plusminus /twosuperior /threesuperior
-/acute /mu /paragraph /bullet
-/cedilla /onesuperior /ordmasculine /guillemotright
-/onequarter /onehalf /threequarters /questiondown
-/Agrave /Aacute /Acircumflex /Atilde
-/Adieresis /Aring /AE /Ccedilla
-/Egrave /Eacute /Ecircumflex /Edieresis
-/Igrave /Iacute /Icircumflex /Idieresis
-/Eth /Ntilde /Ograve /Oacute
-/Ocircumflex /Otilde /Odieresis /multiply
-/Oslash /Ugrave /Uacute /Ucircumflex
-/Udieresis /Yacute /Thorn /germandbls
-/agrave /aacute /acircumflex /atilde
-/adieresis /aring /ae /ccedilla
-/egrave /eacute /ecircumflex /edieresis
-/igrave /iacute /icircumflex /idieresis
-/eth /ntilde /ograve /oacute
-/ocircumflex /otilde /odieresis /divide
-/oslash /ugrave /uacute /ucircumflex
-/udieresis /yacute /thorn /ydieresis
-] def
-%%EndResource
-%%EndProlog
-%%BeginSetup
-%%IncludeResource: font Courier-Bold
-%%IncludeResource: font Courier
-/HFpt_w 10 def
-/HFpt_h 10 def
-/Courier-Bold /HF-gs-font MF
-/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
-/Courier /F-gs-font MF
-/F-gs-font 10 10 SF
-/#copies 1 def
-/d_page_w 520 def
-/d_page_h 747 def
-/d_header_x 0 def
-/d_header_y 747 def
-/d_header_w 520 def
-/d_header_h 0 def
-/d_footer_x 0 def
-/d_footer_y 0 def
-/d_footer_w 520 def
-/d_footer_h 0 def
-/d_output_w 520 def
-/d_output_h 747 def
-/cols 1 def
-userdict/PStoPSxform PStoPSmatrix matrix currentmatrix
- matrix invertmatrix matrix concatmatrix
- matrix invertmatrix put
-%%EndSetup
-%%Page: (0,1) 1
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 1 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 701 M
-(Network Working Group T. Ylonen) s
-5 690 M
-(Internet-Draft SSH Communications Security Corp) s
-5 679 M
-(Expires: March 2, 2003 D. Moffat, Ed.) s
-5 668 M
-( Sun Microsystems, Inc) s
-5 657 M
-( September 2002) s
-5 624 M
-( SSH Authentication Protocol) s
-5 613 M
-( draft-ietf-secsh-userauth-18.txt) s
-5 591 M
-(Status of this Memo) s
-5 569 M
-( This document is an Internet-Draft and is in full conformance with) s
-5 558 M
-( all provisions of Section 10 of RFC2026.) s
-5 536 M
-( Internet-Drafts are working documents of the Internet Engineering) s
-5 525 M
-( Task Force \(IETF\), its areas, and its working groups. Note that other) s
-5 514 M
-( groups may also distribute working documents as Internet-Drafts.) s
-5 492 M
-( Internet-Drafts are draft documents valid for a maximum of six months) s
-5 481 M
-( and may be updated, replaced, or obsoleted by other documents at any) s
-5 470 M
-( time. It is inappropriate to use Internet-Drafts as reference) s
-5 459 M
-( material or to cite them other than as "work in progress.") s
-5 437 M
-( The list of current Internet-Drafts can be accessed at http://) s
-5 426 M
-( www.ietf.org/ietf/1id-abstracts.txt.) s
-5 404 M
-( The list of Internet-Draft Shadow Directories can be accessed at) s
-5 393 M
-( http://www.ietf.org/shadow.html.) s
-5 371 M
-( This Internet-Draft will expire on March 2, 2003.) s
-5 349 M
-(Copyright Notice) s
-5 327 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 305 M
-(Abstract) s
-5 283 M
-( SSH is a protocol for secure remote login and other secure network) s
-5 272 M
-( services over an insecure network. This document describes the SSH) s
-5 261 M
-( authentication protocol framework and public key, password, and) s
-5 250 M
-( host-based client authentication methods. Additional authentication) s
-5 239 M
-( methods are described in separate documents. The SSH authentication) s
-5 228 M
-( protocol runs on top of the SSH transport layer protocol and provides) s
-5 217 M
-( a single authenticated tunnel for the SSH connection protocol.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 1]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 2 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Table of Contents) s
-5 668 M
-( 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 657 M
-( 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3) s
-5 646 M
-( 3. Conventions Used in This Document . . . . . . . . . . . . . 3) s
-5 635 M
-( 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3) s
-5 624 M
-( 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4) s
-5 613 M
-( 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5) s
-5 602 M
-( 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6) s
-5 591 M
-( 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6) s
-5 580 M
-( 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7) s
-5 569 M
-( 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7) s
-5 558 M
-( 3.3 Public Key Authentication Method: publickey . . . . . . . . 8) s
-5 547 M
-( 3.4 Password Authentication Method: password . . . . . . . . . . 10) s
-5 536 M
-( 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11) s
-5 525 M
-( 4. Security Considerations . . . . . . . . . . . . . . . . . . 12) s
-5 514 M
-( Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 503 M
-( Informative . . . . . . . . . . . . . . . . . . . . . . . . 13) s
-5 492 M
-( Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14) s
-5 481 M
-( Intellectual Property and Copyright Statements . . . . . . . 15) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 2]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (2,3) 2
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 3 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(1. Contributors) s
-5 668 M
-( The major original contributors of this document were: Tatu Ylonen,) s
-5 657 M
-( Tero Kivinen, Timo J. Rinne, Sami Lehtinen \(all of SSH Communications) s
-5 646 M
-( Security Corp\), and Markku-Juhani O. Saarinen \(University of) s
-5 635 M
-( Jyvaskyla\)) s
-5 613 M
-( The document editor is: [email protected]. Comments on this) s
-5 602 M
-( internet draft should be sent to the IETF SECSH working group,) s
-5 591 M
-( details at: http://ietf.org/html.charters/secsh-charter.html) s
-5 569 M
-(2. Introduction) s
-5 547 M
-( The SSH authentication protocol is a general-purpose user) s
-5 536 M
-( authentication protocol. It is intended to be run over the SSH) s
-5 525 M
-( transport layer protocol [SSH-TRANS]. This protocol assumes that the) s
-5 514 M
-( underlying protocols provide integrity and confidentiality) s
-5 503 M
-( protection.) s
-5 481 M
-( This document should be read only after reading the SSH architecture) s
-5 470 M
-( document [SSH-ARCH]. This document freely uses terminology and) s
-5 459 M
-( notation from the architecture document without reference or further) s
-5 448 M
-( explanation.) s
-5 426 M
-( The service name for this protocol is "ssh-userauth".) s
-5 404 M
-( When this protocol starts, it receives the session identifier from) s
-5 393 M
-( the lower-level protocol \(this is the exchange hash H from the first) s
-5 382 M
-( key exchange\). The session identifier uniquely identifies this) s
-5 371 M
-( session and is suitable for signing in order to prove ownership of a) s
-5 360 M
-( private key. This protocol also needs to know whether the lower-level) s
-5 349 M
-( protocol provides confidentiality protection.) s
-5 327 M
-(3. Conventions Used in This Document) s
-5 305 M
-( The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",) s
-5 294 M
-( and "MAY" that appear in this document are to be interpreted as) s
-5 283 M
-( described in [RFC2119]) s
-5 261 M
-( The used data types and terminology are specified in the architecture) s
-5 250 M
-( document [SSH-ARCH]) s
-5 228 M
-( The architecture document also discusses the algorithm naming) s
-5 217 M
-( conventions that MUST be used with the SSH protocols.) s
-5 195 M
-(3.1 The Authentication Protocol Framework) s
-5 173 M
-( The server drives the authentication by telling the client which) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 3]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 4 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication methods can be used to continue the exchange at any) s
-5 679 M
-( given time. The client has the freedom to try the methods listed by) s
-5 668 M
-( the server in any order. This gives the server complete control over) s
-5 657 M
-( the authentication process if desired, but also gives enough) s
-5 646 M
-( flexibility for the client to use the methods it supports or that are) s
-5 635 M
-( most convenient for the user, when multiple methods are offered by) s
-5 624 M
-( the server.) s
-5 602 M
-( Authentication methods are identified by their name, as defined in) s
-5 591 M
-( [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as) s
-5 580 M
-( supported. However, it MAY be sent by the client. The server MUST) s
-5 569 M
-( always reject this request, unless the client is to be allowed in) s
-5 558 M
-( without any authentication, in which case the server MUST accept this) s
-5 547 M
-( request. The main purpose of sending this request is to get the list) s
-5 536 M
-( of supported methods from the server.) s
-5 514 M
-( The server SHOULD have a timeout for authentication, and disconnect) s
-5 503 M
-( if the authentication has not been accepted within the timeout) s
-5 492 M
-( period. The RECOMMENDED timeout period is 10 minutes. Additionally,) s
-5 481 M
-( the implementation SHOULD limit the number of failed authentication) s
-5 470 M
-( attempts a client may perform in a single session \(the RECOMMENDED) s
-5 459 M
-( limit is 20 attempts\). If the threshold is exceeded, the server) s
-5 448 M
-( SHOULD disconnect.) s
-5 426 M
-(3.1.1 Authentication Requests) s
-5 404 M
-( All authentication requests MUST use the following message format.) s
-5 393 M
-( Only the first few fields are defined; the remaining fields depend on) s
-5 382 M
-( the authentication method.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name \(in ISO-10646 UTF-8 encoding [RFC2279]\)) s
-5 338 M
-( string service name \(in US-ASCII\)) s
-5 327 M
-( string method name \(US-ASCII\)) s
-5 316 M
-( The rest of the packet is method-specific.) s
-5 294 M
-( The user name and service are repeated in every new authentication) s
-5 283 M
-( attempt, and MAY change. The server implementation MUST carefully) s
-5 272 M
-( check them in every message, and MUST flush any accumulated) s
-5 261 M
-( authentication states if they change. If it is unable to flush some) s
-5 250 M
-( authentication state, it MUST disconnect if the user or service name) s
-5 239 M
-( changes.) s
-5 217 M
-( The service name specifies the service to start after authentication.) s
-5 206 M
-( There may be several different authenticated services provided. If) s
-5 195 M
-( the requested service is not available, the server MAY disconnect) s
-5 184 M
-( immediately or at any later time. Sending a proper disconnect) s
-5 173 M
-( message is RECOMMENDED. In any case, if the service does not exist,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 4]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (4,5) 3
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 5 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authentication MUST NOT be accepted.) s
-5 668 M
-( If the requested user does not exist, the server MAY disconnect, or) s
-5 657 M
-( MAY send a bogus list of acceptable authentication methods, but never) s
-5 646 M
-( accept any. This makes it possible for the server to avoid) s
-5 635 M
-( disclosing information on which accounts exist. In any case, if the) s
-5 624 M
-( user does not exist, the authentication request MUST NOT be accepted.) s
-5 602 M
-( While there is usually little point for clients to send requests that) s
-5 591 M
-( the server does not list as acceptable, sending such requests is not) s
-5 580 M
-( an error, and the server SHOULD simply reject requests that it does) s
-5 569 M
-( not recognize.) s
-5 547 M
-( An authentication request MAY result in a further exchange of) s
-5 536 M
-( messages. All such messages depend on the authentication method) s
-5 525 M
-( used, and the client MAY at any time continue with a new) s
-5 514 M
-( SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST) s
-5 503 M
-( abandon the previous authentication attempt and continue with the new) s
-5 492 M
-( one.) s
-5 470 M
-(3.1.2 Responses to Authentication Requests) s
-5 448 M
-( If the server rejects the authentication request, it MUST respond) s
-5 437 M
-( with the following:) s
-5 415 M
-( byte SSH_MSG_USERAUTH_FAILURE) s
-5 404 M
-( string authentications that can continue) s
-5 393 M
-( boolean partial success) s
-5 371 M
-( "Authentications that can continue" is a comma-separated list of) s
-5 360 M
-( authentication method names that may productively continue the) s
-5 349 M
-( authentication dialog.) s
-5 327 M
-( It is RECOMMENDED that servers only include those methods in the list) s
-5 316 M
-( that are actually useful. However, it is not illegal to include) s
-5 305 M
-( methods that cannot be used to authenticate the user.) s
-5 283 M
-( Already successfully completed authentications SHOULD NOT be included) s
-5 272 M
-( in the list, unless they really should be performed again for some) s
-5 261 M
-( reason.) s
-5 239 M
-( "Partial success" MUST be TRUE if the authentication request to which) s
-5 228 M
-( this is a response was successful. It MUST be FALSE if the request) s
-5 217 M
-( was not successfully processed.) s
-5 195 M
-( When the server accepts authentication, it MUST respond with the) s
-5 184 M
-( following:) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 5]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 6 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( byte SSH_MSG_USERAUTH_SUCCESS) s
-5 668 M
-( Note that this is not sent after each step in a multi-method) s
-5 657 M
-( authentication sequence, but only when the authentication is) s
-5 646 M
-( complete.) s
-5 624 M
-( The client MAY send several authentication requests without waiting) s
-5 613 M
-( for responses from previous requests. The server MUST process each) s
-5 602 M
-( request completely and acknowledge any failed requests with a) s
-5 591 M
-( SSH_MSG_USERAUTH_FAILURE message before processing the next request.) s
-5 569 M
-( A request that results in further exchange of messages will be) s
-5 558 M
-( aborted by a second request. It is not possible to send a second) s
-5 547 M
-( request without waiting for a response from the server, if the first) s
-5 536 M
-( request will result in further exchange of messages. No) s
-5 525 M
-( SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.) s
-5 503 M
-( SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When) s
-5 492 M
-( SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication) s
-5 481 M
-( requests received after that SHOULD be silently ignored.) s
-5 459 M
-( Any non-authentication messages sent by the client after the request) s
-5 448 M
-( that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed) s
-5 437 M
-( to the service being run on top of this protocol. Such messages can) s
-5 426 M
-( be identified by their message numbers \(see Section Message Numbers) s
-5 415 M
-( \(Section 3.2\)\).) s
-5 393 M
-(3.1.3 The "none" Authentication Request) s
-5 371 M
-( A client may request a list of authentication methods that may) s
-5 360 M
-( continue by using the "none" authentication method.) s
-5 338 M
-( If no authentication at all is needed for the user, the server MUST) s
-5 327 M
-( return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return) s
-5 316 M
-( SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of) s
-5 305 M
-( authentication methods that can continue.) s
-5 283 M
-( This method MUST NOT be listed as supported by the server.) s
-5 261 M
-(3.1.4 Completion of User Authentication) s
-5 239 M
-( Authentication is complete when the server has responded with) s
-5 228 M
-( SSH_MSG_USERAUTH_SUCCESS; all authentication related messages) s
-5 217 M
-( received after sending this message SHOULD be silently ignored.) s
-5 195 M
-( After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the) s
-5 184 M
-( requested service.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 6]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (6,7) 4
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 7 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.1.5 Banner Message) s
-5 668 M
-( In some jurisdictions, sending a warning message before) s
-5 657 M
-( authentication may be relevant for getting legal protection. Many) s
-5 646 M
-( UNIX machines, for example, normally display text from `/etc/issue',) s
-5 635 M
-( or use "tcp wrappers" or similar software to display a banner before) s
-5 624 M
-( issuing a login prompt.) s
-5 602 M
-( The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time) s
-5 591 M
-( before authentication is successful. This message contains text to) s
-5 580 M
-( be displayed to the client user before authentication is attempted.) s
-5 569 M
-( The format is as follows:) s
-5 547 M
-( byte SSH_MSG_USERAUTH_BANNER) s
-5 536 M
-( string message \(ISO-10646 UTF-8\)) s
-5 525 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 503 M
-( The client SHOULD by default display the message on the screen.) s
-5 492 M
-( However, since the message is likely to be sent for every login) s
-5 481 M
-( attempt, and since some client software will need to open a separate) s
-5 470 M
-( window for this warning, the client software may allow the user to) s
-5 459 M
-( explicitly disable the display of banners from the server. The) s
-5 448 M
-( message may consist of multiple lines.) s
-5 426 M
-( If the message string is displayed, control character filtering) s
-5 415 M
-( discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending) s
-5 404 M
-( terminal control characters.) s
-5 382 M
-(3.2 Authentication Protocol Message Numbers) s
-5 360 M
-( All message numbers used by this authentication protocol are in the) s
-5 349 M
-( range from 50 to 79, which is part of the range reserved for) s
-5 338 M
-( protocols running on top of the SSH transport layer protocol.) s
-5 316 M
-( Message numbers of 80 and higher are reserved for protocols running) s
-5 305 M
-( after this authentication protocol, so receiving one of them before) s
-5 294 M
-( authentication is complete is an error, to which the server MUST) s
-5 283 M
-( respond by disconnecting \(preferably with a proper disconnect message) s
-5 272 M
-( sent first to ease troubleshooting\).) s
-5 250 M
-( After successful authentication, such messages are passed to the) s
-5 239 M
-( higher-level service.) s
-5 217 M
-( These are the general authentication message codes:) s
-5 195 M
-( #define SSH_MSG_USERAUTH_REQUEST 50) s
-5 184 M
-( #define SSH_MSG_USERAUTH_FAILURE 51) s
-5 173 M
-( #define SSH_MSG_USERAUTH_SUCCESS 52) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 7]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 8 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( #define SSH_MSG_USERAUTH_BANNER 53) s
-5 668 M
-( In addition to the above, there is a range of message numbers) s
-5 657 M
-( \(60..79\) reserved for method-specific messages. These messages are) s
-5 646 M
-( only sent by the server \(client sends only SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( messages\). Different authentication methods reuse the same message) s
-5 624 M
-( numbers.) s
-5 602 M
-(3.3 Public Key Authentication Method: publickey) s
-5 580 M
-( The only REQUIRED authentication method is public key authentication.) s
-5 569 M
-( All implementations MUST support this method; however, not all users) s
-5 558 M
-( need to have public keys, and most local policies are not likely to) s
-5 547 M
-( require public key authentication for all users in the near future.) s
-5 525 M
-( With this method, the possession of a private key serves as) s
-5 514 M
-( authentication. This method works by sending a signature created) s
-5 503 M
-( with a private key of the user. The server MUST check that the key) s
-5 492 M
-( is a valid authenticator for the user, and MUST check that the) s
-5 481 M
-( signature is valid. If both hold, the authentication request MUST be) s
-5 470 M
-( accepted; otherwise it MUST be rejected. \(Note that the server MAY) s
-5 459 M
-( require additional authentications after successful authentication.\)) s
-5 437 M
-( Private keys are often stored in an encrypted form at the client) s
-5 426 M
-( host, and the user must supply a passphrase before the signature can) s
-5 415 M
-( be generated. Even if they are not, the signing operation involves) s
-5 404 M
-( some expensive computation. To avoid unnecessary processing and user) s
-5 393 M
-( interaction, the following message is provided for querying whether) s
-5 382 M
-( authentication using the key would be acceptable.) s
-5 360 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 349 M
-( string user name) s
-5 338 M
-( string service) s
-5 327 M
-( string "publickey") s
-5 316 M
-( boolean FALSE) s
-5 305 M
-( string public key algorithm name) s
-5 294 M
-( string public key blob) s
-5 272 M
-( Public key algorithms are defined in the transport layer) s
-5 261 M
-( specification [SSH-TRANS]. The public key blob may contain) s
-5 250 M
-( certificates.) s
-5 228 M
-( Any public key algorithm may be offered for use in authentication.) s
-5 217 M
-( In particular, the list is not constrained by what was negotiated) s
-5 206 M
-( during key exchange. If the server does not support some algorithm,) s
-5 195 M
-( it MUST simply reject the request.) s
-5 173 M
-( The server MUST respond to this message with either) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 8]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (8,9) 5
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 9 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( SSH_MSG_USERAUTH_FAILURE or with the following:) s
-5 668 M
-( byte SSH_MSG_USERAUTH_PK_OK) s
-5 657 M
-( string public key algorithm name from the request) s
-5 646 M
-( string public key blob from the request) s
-5 624 M
-( To perform actual authentication, the client MAY then send a) s
-5 613 M
-( signature generated using the private key. The client MAY send the) s
-5 602 M
-( signature directly without first verifying whether the key is) s
-5 591 M
-( acceptable. The signature is sent using the following packet:) s
-5 569 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 558 M
-( string user name) s
-5 547 M
-( string service) s
-5 536 M
-( string "publickey") s
-5 525 M
-( boolean TRUE) s
-5 514 M
-( string public key algorithm name) s
-5 503 M
-( string public key to be used for authentication) s
-5 492 M
-( string signature) s
-5 470 M
-( Signature is a signature by the corresponding private key over the) s
-5 459 M
-( following data, in the following order:) s
-5 437 M
-( string session identifier) s
-5 426 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 415 M
-( string user name) s
-5 404 M
-( string service) s
-5 393 M
-( string "publickey") s
-5 382 M
-( boolean TRUE) s
-5 371 M
-( string public key algorithm name) s
-5 360 M
-( string public key to be used for authentication) s
-5 338 M
-( When the server receives this message, it MUST check whether the) s
-5 327 M
-( supplied key is acceptable for authentication, and if so, it MUST) s
-5 316 M
-( check whether the signature is correct.) s
-5 294 M
-( If both checks succeed, this method is successful. Note that the) s
-5 283 M
-( server may require additional authentications. The server MUST) s
-5 272 M
-( respond with SSH_MSG_USERAUTH_SUCCESS \(if no more authentications are) s
-5 261 M
-( needed\), or SSH_MSG_USERAUTH_FAILURE \(if the request failed, or more) s
-5 250 M
-( authentications are needed\).) s
-5 228 M
-( The following method-specific message numbers are used by the) s
-5 217 M
-( publickey authentication method.) s
-5 195 M
-( /* Key-based */) s
-5 184 M
-( #define SSH_MSG_USERAUTH_PK_OK 60) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 9]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 10 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(3.4 Password Authentication Method: password) s
-5 668 M
-( Password authentication uses the following packets. Note that a) s
-5 657 M
-( server MAY request the user to change the password. All) s
-5 646 M
-( implementations SHOULD support password authentication.) s
-5 624 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 613 M
-( string user name) s
-5 602 M
-( string service) s
-5 591 M
-( string "password") s
-5 580 M
-( boolean FALSE) s
-5 569 M
-( string plaintext password \(ISO-10646 UTF-8\)) s
-5 547 M
-( Note that the password is encoded in ISO-10646 UTF-8. It is up to) s
-5 536 M
-( the server how it interprets the password and validates it against) s
-5 525 M
-( the password database. However, if the client reads the password in) s
-5 514 M
-( some other encoding \(e.g., ISO 8859-1 \(ISO Latin1\)\), it MUST convert) s
-5 503 M
-( the password to ISO-10646 UTF-8 before transmitting, and the server) s
-5 492 M
-( MUST convert the password to the encoding used on that system for) s
-5 481 M
-( passwords.) s
-5 459 M
-( Note that even though the cleartext password is transmitted in the) s
-5 448 M
-( packet, the entire packet is encrypted by the transport layer. Both) s
-5 437 M
-( the server and the client should check whether the underlying) s
-5 426 M
-( transport layer provides confidentiality \(i.e., if encryption is) s
-5 415 M
-( being used\). If no confidentiality is provided \(none cipher\),) s
-5 404 M
-( password authentication SHOULD be disabled. If there is no) s
-5 393 M
-( confidentiality or no MAC, password change SHOULD be disabled.) s
-5 371 M
-( Normally, the server responds to this message with success or) s
-5 360 M
-( failure. However, if the password has expired the server SHOULD) s
-5 349 M
-( indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.) s
-5 338 M
-( In anycase the server MUST NOT allow an expired password to be used) s
-5 327 M
-( for authentication.) s
-5 305 M
-( byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) s
-5 294 M
-( string prompt \(ISO-10646 UTF-8\)) s
-5 283 M
-( string language tag \(as defined in [RFC3066]\)) s
-5 261 M
-( In this case, the client MAY continue with a different authentication) s
-5 250 M
-( method, or request a new password from the user and retry password) s
-5 239 M
-( authentication using the following message. The client MAY also send) s
-5 228 M
-( this message instead of the normal password authentication request) s
-5 217 M
-( without the server asking for it.) s
-5 195 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 184 M
-( string user name) s
-5 173 M
-( string service) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 10]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (10,11) 6
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 11 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( string "password") s
-5 679 M
-( boolean TRUE) s
-5 668 M
-( string plaintext old password \(ISO-10646 UTF-8\)) s
-5 657 M
-( string plaintext new password \(ISO-10646 UTF-8\)) s
-5 635 M
-( The server must reply to request message with) s
-5 624 M
-( SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another) s
-5 613 M
-( SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as) s
-5 602 M
-( follows:) s
-5 580 M
-( SSH_MSG_USERAUTH_SUCCESS The password has been changed, and) s
-5 569 M
-( authentication has been successfully completed.) s
-5 547 M
-( SSH_MSG_USERAUTH_FAILURE with partial success The password has) s
-5 536 M
-( been changed, but more authentications are needed.) s
-5 514 M
-( SSH_MSG_USERAUTH_FAILURE without partial success The password has) s
-5 503 M
-( not been changed. Either password changing was not supported, or) s
-5 492 M
-( the old password was bad. Note that if the server has already) s
-5 481 M
-( sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports) s
-5 470 M
-( changing the password.) s
-5 448 M
-( SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because) s
-5 437 M
-( the new password was not acceptable \(e.g. too easy to guess\).) s
-5 415 M
-( The following method-specific message numbers are used by the) s
-5 404 M
-( password authentication method.) s
-5 382 M
-( #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60) s
-5 349 M
-(3.5 Host-Based Authentication: hostbased) s
-5 327 M
-( Some sites wish to allow authentication based on the host where the) s
-5 316 M
-( user is coming from, and the user name on the remote host. While) s
-5 305 M
-( this form of authentication is not suitable for high-security sites,) s
-5 294 M
-( it can be very convenient in many environments. This form of) s
-5 283 M
-( authentication is OPTIONAL. When used, special care SHOULD be taken) s
-5 272 M
-( to prevent a regular user from obtaining the private host key.) s
-5 250 M
-( The client requests this form of authentication by sending the) s
-5 239 M
-( following message. It is similar to the UNIX "rhosts" and) s
-5 228 M
-( "hosts.equiv" styles of authentication, except that the identity of) s
-5 217 M
-( the client host is checked more rigorously.) s
-5 195 M
-( This method works by having the client send a signature created with) s
-5 184 M
-( the private key of the client host, which the server checks with that) s
-5 173 M
-( host's public key. Once the client host's identity is established,) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 11]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 12 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( authorization \(but no further authentication\) is performed based on) s
-5 679 M
-( the user names on the server and the client, and the client host) s
-5 668 M
-( name.) s
-5 646 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 635 M
-( string user name) s
-5 624 M
-( string service) s
-5 613 M
-( string "hostbased") s
-5 602 M
-( string public key algorithm for host key) s
-5 591 M
-( string public host key and certificates for client host) s
-5 580 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 569 M
-( string user name on the client host \(ISO-10646 UTF-8\)) s
-5 558 M
-( string signature) s
-5 536 M
-( Public key algorithm names for use in "public key algorithm for host) s
-5 525 M
-( key" are defined in the transport layer specification. The "public) s
-5 514 M
-( host key for client host" may include certificates.) s
-5 492 M
-( Signature is a signature with the private host key of the following) s
-5 481 M
-( data, in this order:) s
-5 459 M
-( string session identifier) s
-5 448 M
-( byte SSH_MSG_USERAUTH_REQUEST) s
-5 437 M
-( string user name) s
-5 426 M
-( string service) s
-5 415 M
-( string "hostbased") s
-5 404 M
-( string public key algorithm for host key) s
-5 393 M
-( string public host key and certificates for client host) s
-5 382 M
-( string client host name \(FQDN; US-ASCII\)) s
-5 371 M
-( string user name on the client host\(ISO-10646 UTF-8\)) s
-5 349 M
-( The server MUST verify that the host key actually belongs to the) s
-5 338 M
-( client host named in the message, that the given user on that host is) s
-5 327 M
-( allowed to log in, and that the signature is a valid signature on the) s
-5 316 M
-( appropriate value by the given host key. The server MAY ignore the) s
-5 305 M
-( client user name, if it wants to authenticate only the client host.) s
-5 283 M
-( It is RECOMMENDED that whenever possible, the server perform) s
-5 272 M
-( additional checks to verify that the network address obtained from) s
-5 261 M
-( the \(untrusted\) network matches the given client host name. This) s
-5 250 M
-( makes exploiting compromised host keys more difficult. Note that) s
-5 239 M
-( this may require special handling for connections coming through a) s
-5 228 M
-( firewall.) s
-5 206 M
-(4. Security Considerations) s
-5 184 M
-( The purpose of this protocol is to perform client user) s
-5 173 M
-( authentication. It assumed that this runs over a secure transport) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 12]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (12,13) 7
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 13 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( layer protocol, which has already authenticated the server machine,) s
-5 679 M
-( established an encrypted communications channel, and computed a) s
-5 668 M
-( unique session identifier for this session. The transport layer) s
-5 657 M
-( provides forward secrecy for password authentication and other) s
-5 646 M
-( methods that rely on secret data.) s
-5 624 M
-( Full security considerations for this protocol are provided in) s
-5 613 M
-( Section 8 of [SSH-ARCH]) s
-5 591 M
-(Normative) s
-5 569 M
-( [SSH-ARCH]) s
-5 558 M
-( Ylonen, T., "SSH Protocol Architecture", I-D) s
-5 547 M
-( draft-ietf-architecture-15.txt, Oct 2003.) s
-5 525 M
-( [SSH-TRANS]) s
-5 514 M
-( Ylonen, T., "SSH Transport Layer Protocol", I-D) s
-5 503 M
-( draft-ietf-transport-17.txt, Oct 2003.) s
-5 481 M
-( [SSH-USERAUTH]) s
-5 470 M
-( Ylonen, T., "SSH Authentication Protocol", I-D) s
-5 459 M
-( draft-ietf-userauth-18.txt, Oct 2003.) s
-5 437 M
-( [SSH-CONNECT]) s
-5 426 M
-( Ylonen, T., "SSH Connection Protocol", I-D) s
-5 415 M
-( draft-ietf-connect-18.txt, Oct 2003.) s
-5 393 M
-( [SSH-NUMBERS]) s
-5 382 M
-( Lehtinen, S. and D. Moffat, "SSH Protocol Assigned) s
-5 371 M
-( Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct) s
-5 360 M
-( 2003.) s
-5 338 M
-( [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate) s
-5 327 M
-( Requirement Levels", BCP 14, RFC 2119, March 1997.) s
-5 305 M
-(Informative) s
-5 283 M
-( [RFC3066] Alvestrand, H., "Tags for the Identification of) s
-5 272 M
-( Languages", BCP 47, RFC 3066, January 2001.) s
-5 250 M
-( [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO) s
-5 239 M
-( 10646", RFC 2279, January 1998.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 13]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 14 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Authors' Addresses) s
-5 668 M
-( Tatu Ylonen) s
-5 657 M
-( SSH Communications Security Corp) s
-5 646 M
-( Fredrikinkatu 42) s
-5 635 M
-( HELSINKI FIN-00100) s
-5 624 M
-( Finland) s
-5 602 M
-( EMail: [email protected]) s
-5 569 M
-( Darren J. Moffat \(editor\)) s
-5 558 M
-( Sun Microsystems, Inc) s
-5 547 M
-( 17 Network Circle) s
-5 536 M
-( Menlo Park 95025) s
-5 525 M
-( USA) s
-5 503 M
-( EMail: [email protected]) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 14]) s
-_R
-S
-PStoPSsaved restore
-%%Page: (14,15) 8
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 0.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-/showpage{}def/copypage{}def/erasepage{}def
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 15 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-(Intellectual Property Statement) s
-5 668 M
-( The IETF takes no position regarding the validity or scope of any) s
-5 657 M
-( intellectual property or other rights that might be claimed to) s
-5 646 M
-( pertain to the implementation or use of the technology described in) s
-5 635 M
-( this document or the extent to which any license under such rights) s
-5 624 M
-( might or might not be available; neither does it represent that it) s
-5 613 M
-( has made any effort to identify any such rights. Information on the) s
-5 602 M
-( IETF's procedures with respect to rights in standards-track and) s
-5 591 M
-( standards-related documentation can be found in BCP-11. Copies of) s
-5 580 M
-( claims of rights made available for publication and any assurances of) s
-5 569 M
-( licenses to be made available, or the result of an attempt made to) s
-5 558 M
-( obtain a general license or permission for the use of such) s
-5 547 M
-( proprietary rights by implementors or users of this specification can) s
-5 536 M
-( be obtained from the IETF Secretariat.) s
-5 514 M
-( The IETF invites any interested party to bring to its attention any) s
-5 503 M
-( copyrights, patents or patent applications, or other proprietary) s
-5 492 M
-( rights which may cover technology that may be required to practice) s
-5 481 M
-( this standard. Please address the information to the IETF Executive) s
-5 470 M
-( Director.) s
-5 448 M
-( The IETF has been notified of intellectual property rights claimed in) s
-5 437 M
-( regard to some or all of the specification contained in this) s
-5 426 M
-( document. For more information consult the online list of claimed) s
-5 415 M
-( rights.) s
-5 382 M
-(Full Copyright Statement) s
-5 360 M
-( Copyright \(C\) The Internet Society \(2002\). All Rights Reserved.) s
-5 338 M
-( This document and translations of it may be copied and furnished to) s
-5 327 M
-( others, and derivative works that comment on or otherwise explain it) s
-5 316 M
-( or assist in its implementation may be prepared, copied, published) s
-5 305 M
-( and distributed, in whole or in part, without restriction of any) s
-5 294 M
-( kind, provided that the above copyright notice and this paragraph are) s
-5 283 M
-( included on all such copies and derivative works. However, this) s
-5 272 M
-( document itself may not be modified in any way, such as by removing) s
-5 261 M
-( the copyright notice or references to the Internet Society or other) s
-5 250 M
-( Internet organizations, except as needed for the purpose of) s
-5 239 M
-( developing Internet standards in which case the procedures for) s
-5 228 M
-( copyrights defined in the Internet Standards process must be) s
-5 217 M
-( followed, or as required to translate it into languages other than) s
-5 206 M
-( English.) s
-5 184 M
-( The limited permissions granted above are perpetual and will not be) s
-5 173 M
-( revoked by the Internet Society or its successors or assignees.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 15]) s
-_R
-S
-PStoPSsaved restore
-userdict/PStoPSsaved save put
-PStoPSmatrix setmatrix
-595.000000 421.271378 translate
-90 rotate
-0.706651 dup scale
-userdict/PStoPSmatrix matrix currentmatrix put
-userdict/PStoPSclip{0 0 moveto
- 595.000000 0 rlineto 0 842.000000 rlineto -595.000000 0 rlineto
- closepath}put initclip
-PStoPSxform concat
-%%BeginPageSetup
-_S
-75 0 translate
-/pagenum 16 def
-/fname () def
-/fdir () def
-/ftail () def
-/user_header_p false def
-%%EndPageSetup
-5 723 M
-(Internet-Draft SSH Authentication Protocol September 2002) s
-5 690 M
-( This document and the information contained herein is provided on an) s
-5 679 M
-( "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING) s
-5 668 M
-( TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING) s
-5 657 M
-( BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION) s
-5 646 M
-( HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF) s
-5 635 M
-( MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.) s
-5 602 M
-(Acknowledgment) s
-5 580 M
-( Funding for the RFC Editor function is currently provided by the) s
-5 569 M
-( Internet Society.) s
-5 129 M
-(Ylonen & Moffat Expires March 2, 2003 [Page 16]) s
-_R
-S
-PStoPSsaved restore
-%%Trailer
-%%Pages: 16
-%%DocumentNeededResources: font Courier-Bold Courier
-%%EOF
diff --git a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt b/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
deleted file mode 100644
index 9dae578a35..0000000000
--- a/lib/ssh/doc/standard/draft-ietf-secsh-userauth-18.txt
+++ /dev/null
@@ -1,896 +0,0 @@
-
-
-
-Network Working Group T. Ylonen
-Internet-Draft SSH Communications Security Corp
-Expires: March 2, 2003 D. Moffat, Ed.
- Sun Microsystems, Inc
- September 2002
-
-
- SSH Authentication Protocol
- draft-ietf-secsh-userauth-18.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance with
- all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that other
- groups may also distribute working documents as Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six months
- and may be updated, replaced, or obsoleted by other documents at any
- time. It is inappropriate to use Internet-Drafts as reference
- material or to cite them other than as "work in progress."
-
- The list of current Internet-Drafts can be accessed at http://
- www.ietf.org/ietf/1id-abstracts.txt.
-
- The list of Internet-Draft Shadow Directories can be accessed at
- http://www.ietf.org/shadow.html.
-
- This Internet-Draft will expire on March 2, 2003.
-
-Copyright Notice
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
-Abstract
-
- SSH is a protocol for secure remote login and other secure network
- services over an insecure network. This document describes the SSH
- authentication protocol framework and public key, password, and
- host-based client authentication methods. Additional authentication
- methods are described in separate documents. The SSH authentication
- protocol runs on top of the SSH transport layer protocol and provides
- a single authenticated tunnel for the SSH connection protocol.
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 1]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Table of Contents
-
- 1. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 3
- 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
- 3. Conventions Used in This Document . . . . . . . . . . . . . 3
- 3.1 The Authentication Protocol Framework . . . . . . . . . . . 3
- 3.1.1 Authentication Requests . . . . . . . . . . . . . . . . . . 4
- 3.1.2 Responses to Authentication Requests . . . . . . . . . . . . 5
- 3.1.3 The "none" Authentication Request . . . . . . . . . . . . . 6
- 3.1.4 Completion of User Authentication . . . . . . . . . . . . . 6
- 3.1.5 Banner Message . . . . . . . . . . . . . . . . . . . . . . . 7
- 3.2 Authentication Protocol Message Numbers . . . . . . . . . . 7
- 3.3 Public Key Authentication Method: publickey . . . . . . . . 8
- 3.4 Password Authentication Method: password . . . . . . . . . . 10
- 3.5 Host-Based Authentication: hostbased . . . . . . . . . . . . 11
- 4. Security Considerations . . . . . . . . . . . . . . . . . . 12
- Normative . . . . . . . . . . . . . . . . . . . . . . . . . 13
- Informative . . . . . . . . . . . . . . . . . . . . . . . . 13
- Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 14
- Intellectual Property and Copyright Statements . . . . . . . 15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 2]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-1. Contributors
-
- The major original contributors of this document were: Tatu Ylonen,
- Tero Kivinen, Timo J. Rinne, Sami Lehtinen (all of SSH Communications
- Security Corp), and Markku-Juhani O. Saarinen (University of
- Jyvaskyla)
-
- The document editor is: [email protected]. Comments on this
- internet draft should be sent to the IETF SECSH working group,
- details at: http://ietf.org/html.charters/secsh-charter.html
-
-2. Introduction
-
- The SSH authentication protocol is a general-purpose user
- authentication protocol. It is intended to be run over the SSH
- transport layer protocol [SSH-TRANS]. This protocol assumes that the
- underlying protocols provide integrity and confidentiality
- protection.
-
- This document should be read only after reading the SSH architecture
- document [SSH-ARCH]. This document freely uses terminology and
- notation from the architecture document without reference or further
- explanation.
-
- The service name for this protocol is "ssh-userauth".
-
- When this protocol starts, it receives the session identifier from
- the lower-level protocol (this is the exchange hash H from the first
- key exchange). The session identifier uniquely identifies this
- session and is suitable for signing in order to prove ownership of a
- private key. This protocol also needs to know whether the lower-level
- protocol provides confidentiality protection.
-
-3. Conventions Used in This Document
-
- The keywords "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
- and "MAY" that appear in this document are to be interpreted as
- described in [RFC2119]
-
- The used data types and terminology are specified in the architecture
- document [SSH-ARCH]
-
- The architecture document also discusses the algorithm naming
- conventions that MUST be used with the SSH protocols.
-
-3.1 The Authentication Protocol Framework
-
- The server drives the authentication by telling the client which
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 3]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication methods can be used to continue the exchange at any
- given time. The client has the freedom to try the methods listed by
- the server in any order. This gives the server complete control over
- the authentication process if desired, but also gives enough
- flexibility for the client to use the methods it supports or that are
- most convenient for the user, when multiple methods are offered by
- the server.
-
- Authentication methods are identified by their name, as defined in
- [SSH-ARCH]. The "none" method is reserved, and MUST NOT be listed as
- supported. However, it MAY be sent by the client. The server MUST
- always reject this request, unless the client is to be allowed in
- without any authentication, in which case the server MUST accept this
- request. The main purpose of sending this request is to get the list
- of supported methods from the server.
-
- The server SHOULD have a timeout for authentication, and disconnect
- if the authentication has not been accepted within the timeout
- period. The RECOMMENDED timeout period is 10 minutes. Additionally,
- the implementation SHOULD limit the number of failed authentication
- attempts a client may perform in a single session (the RECOMMENDED
- limit is 20 attempts). If the threshold is exceeded, the server
- SHOULD disconnect.
-
-3.1.1 Authentication Requests
-
- All authentication requests MUST use the following message format.
- Only the first few fields are defined; the remaining fields depend on
- the authentication method.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name (in ISO-10646 UTF-8 encoding [RFC2279])
- string service name (in US-ASCII)
- string method name (US-ASCII)
- The rest of the packet is method-specific.
-
- The user name and service are repeated in every new authentication
- attempt, and MAY change. The server implementation MUST carefully
- check them in every message, and MUST flush any accumulated
- authentication states if they change. If it is unable to flush some
- authentication state, it MUST disconnect if the user or service name
- changes.
-
- The service name specifies the service to start after authentication.
- There may be several different authenticated services provided. If
- the requested service is not available, the server MAY disconnect
- immediately or at any later time. Sending a proper disconnect
- message is RECOMMENDED. In any case, if the service does not exist,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 4]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authentication MUST NOT be accepted.
-
- If the requested user does not exist, the server MAY disconnect, or
- MAY send a bogus list of acceptable authentication methods, but never
- accept any. This makes it possible for the server to avoid
- disclosing information on which accounts exist. In any case, if the
- user does not exist, the authentication request MUST NOT be accepted.
-
- While there is usually little point for clients to send requests that
- the server does not list as acceptable, sending such requests is not
- an error, and the server SHOULD simply reject requests that it does
- not recognize.
-
- An authentication request MAY result in a further exchange of
- messages. All such messages depend on the authentication method
- used, and the client MAY at any time continue with a new
- SSH_MSG_USERAUTH_REQUEST message, in which case the server MUST
- abandon the previous authentication attempt and continue with the new
- one.
-
-3.1.2 Responses to Authentication Requests
-
- If the server rejects the authentication request, it MUST respond
- with the following:
-
- byte SSH_MSG_USERAUTH_FAILURE
- string authentications that can continue
- boolean partial success
-
- "Authentications that can continue" is a comma-separated list of
- authentication method names that may productively continue the
- authentication dialog.
-
- It is RECOMMENDED that servers only include those methods in the list
- that are actually useful. However, it is not illegal to include
- methods that cannot be used to authenticate the user.
-
- Already successfully completed authentications SHOULD NOT be included
- in the list, unless they really should be performed again for some
- reason.
-
- "Partial success" MUST be TRUE if the authentication request to which
- this is a response was successful. It MUST be FALSE if the request
- was not successfully processed.
-
- When the server accepts authentication, it MUST respond with the
- following:
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 5]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- byte SSH_MSG_USERAUTH_SUCCESS
-
- Note that this is not sent after each step in a multi-method
- authentication sequence, but only when the authentication is
- complete.
-
- The client MAY send several authentication requests without waiting
- for responses from previous requests. The server MUST process each
- request completely and acknowledge any failed requests with a
- SSH_MSG_USERAUTH_FAILURE message before processing the next request.
-
- A request that results in further exchange of messages will be
- aborted by a second request. It is not possible to send a second
- request without waiting for a response from the server, if the first
- request will result in further exchange of messages. No
- SSH_MSG_USERAUTH_FAILURE message will be sent for the aborted method.
-
- SSH_MSG_USERAUTH_SUCCESS MUST be sent only once. When
- SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication
- requests received after that SHOULD be silently ignored.
-
- Any non-authentication messages sent by the client after the request
- that resulted in SSH_MSG_USERAUTH_SUCCESS being sent MUST be passed
- to the service being run on top of this protocol. Such messages can
- be identified by their message numbers (see Section Message Numbers
- (Section 3.2)).
-
-3.1.3 The "none" Authentication Request
-
- A client may request a list of authentication methods that may
- continue by using the "none" authentication method.
-
- If no authentication at all is needed for the user, the server MUST
- return SSH_MSG_USERAUTH_SUCCESS. Otherwise, the server MUST return
- SSH_MSG_USERAUTH_FAILURE and MAY return with it a list of
- authentication methods that can continue.
-
- This method MUST NOT be listed as supported by the server.
-
-3.1.4 Completion of User Authentication
-
- Authentication is complete when the server has responded with
- SSH_MSG_USERAUTH_SUCCESS; all authentication related messages
- received after sending this message SHOULD be silently ignored.
-
- After sending SSH_MSG_USERAUTH_SUCCESS, the server starts the
- requested service.
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 6]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.1.5 Banner Message
-
- In some jurisdictions, sending a warning message before
- authentication may be relevant for getting legal protection. Many
- UNIX machines, for example, normally display text from `/etc/issue',
- or use "tcp wrappers" or similar software to display a banner before
- issuing a login prompt.
-
- The SSH server may send a SSH_MSG_USERAUTH_BANNER message at any time
- before authentication is successful. This message contains text to
- be displayed to the client user before authentication is attempted.
- The format is as follows:
-
- byte SSH_MSG_USERAUTH_BANNER
- string message (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- The client SHOULD by default display the message on the screen.
- However, since the message is likely to be sent for every login
- attempt, and since some client software will need to open a separate
- window for this warning, the client software may allow the user to
- explicitly disable the display of banners from the server. The
- message may consist of multiple lines.
-
- If the message string is displayed, control character filtering
- discussed in [SSH-ARCH] SHOULD be used to avoid attacks by sending
- terminal control characters.
-
-3.2 Authentication Protocol Message Numbers
-
- All message numbers used by this authentication protocol are in the
- range from 50 to 79, which is part of the range reserved for
- protocols running on top of the SSH transport layer protocol.
-
- Message numbers of 80 and higher are reserved for protocols running
- after this authentication protocol, so receiving one of them before
- authentication is complete is an error, to which the server MUST
- respond by disconnecting (preferably with a proper disconnect message
- sent first to ease troubleshooting).
-
- After successful authentication, such messages are passed to the
- higher-level service.
-
- These are the general authentication message codes:
-
- #define SSH_MSG_USERAUTH_REQUEST 50
- #define SSH_MSG_USERAUTH_FAILURE 51
- #define SSH_MSG_USERAUTH_SUCCESS 52
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 7]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- #define SSH_MSG_USERAUTH_BANNER 53
-
- In addition to the above, there is a range of message numbers
- (60..79) reserved for method-specific messages. These messages are
- only sent by the server (client sends only SSH_MSG_USERAUTH_REQUEST
- messages). Different authentication methods reuse the same message
- numbers.
-
-3.3 Public Key Authentication Method: publickey
-
- The only REQUIRED authentication method is public key authentication.
- All implementations MUST support this method; however, not all users
- need to have public keys, and most local policies are not likely to
- require public key authentication for all users in the near future.
-
- With this method, the possession of a private key serves as
- authentication. This method works by sending a signature created
- with a private key of the user. The server MUST check that the key
- is a valid authenticator for the user, and MUST check that the
- signature is valid. If both hold, the authentication request MUST be
- accepted; otherwise it MUST be rejected. (Note that the server MAY
- require additional authentications after successful authentication.)
-
- Private keys are often stored in an encrypted form at the client
- host, and the user must supply a passphrase before the signature can
- be generated. Even if they are not, the signing operation involves
- some expensive computation. To avoid unnecessary processing and user
- interaction, the following message is provided for querying whether
- authentication using the key would be acceptable.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean FALSE
- string public key algorithm name
- string public key blob
-
- Public key algorithms are defined in the transport layer
- specification [SSH-TRANS]. The public key blob may contain
- certificates.
-
- Any public key algorithm may be offered for use in authentication.
- In particular, the list is not constrained by what was negotiated
- during key exchange. If the server does not support some algorithm,
- it MUST simply reject the request.
-
- The server MUST respond to this message with either
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 8]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- SSH_MSG_USERAUTH_FAILURE or with the following:
-
- byte SSH_MSG_USERAUTH_PK_OK
- string public key algorithm name from the request
- string public key blob from the request
-
- To perform actual authentication, the client MAY then send a
- signature generated using the private key. The client MAY send the
- signature directly without first verifying whether the key is
- acceptable. The signature is sent using the following packet:
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
- string signature
-
- Signature is a signature by the corresponding private key over the
- following data, in the following order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "publickey"
- boolean TRUE
- string public key algorithm name
- string public key to be used for authentication
-
- When the server receives this message, it MUST check whether the
- supplied key is acceptable for authentication, and if so, it MUST
- check whether the signature is correct.
-
- If both checks succeed, this method is successful. Note that the
- server may require additional authentications. The server MUST
- respond with SSH_MSG_USERAUTH_SUCCESS (if no more authentications are
- needed), or SSH_MSG_USERAUTH_FAILURE (if the request failed, or more
- authentications are needed).
-
- The following method-specific message numbers are used by the
- publickey authentication method.
-
- /* Key-based */
- #define SSH_MSG_USERAUTH_PK_OK 60
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 9]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-3.4 Password Authentication Method: password
-
- Password authentication uses the following packets. Note that a
- server MAY request the user to change the password. All
- implementations SHOULD support password authentication.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "password"
- boolean FALSE
- string plaintext password (ISO-10646 UTF-8)
-
- Note that the password is encoded in ISO-10646 UTF-8. It is up to
- the server how it interprets the password and validates it against
- the password database. However, if the client reads the password in
- some other encoding (e.g., ISO 8859-1 (ISO Latin1)), it MUST convert
- the password to ISO-10646 UTF-8 before transmitting, and the server
- MUST convert the password to the encoding used on that system for
- passwords.
-
- Note that even though the cleartext password is transmitted in the
- packet, the entire packet is encrypted by the transport layer. Both
- the server and the client should check whether the underlying
- transport layer provides confidentiality (i.e., if encryption is
- being used). If no confidentiality is provided (none cipher),
- password authentication SHOULD be disabled. If there is no
- confidentiality or no MAC, password change SHOULD be disabled.
-
- Normally, the server responds to this message with success or
- failure. However, if the password has expired the server SHOULD
- indicate this by responding with SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.
- In anycase the server MUST NOT allow an expired password to be used
- for authentication.
-
- byte SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
- string prompt (ISO-10646 UTF-8)
- string language tag (as defined in [RFC3066])
-
- In this case, the client MAY continue with a different authentication
- method, or request a new password from the user and retry password
- authentication using the following message. The client MAY also send
- this message instead of the normal password authentication request
- without the server asking for it.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 10]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- string "password"
- boolean TRUE
- string plaintext old password (ISO-10646 UTF-8)
- string plaintext new password (ISO-10646 UTF-8)
-
- The server must reply to request message with
- SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
- SSH_MSG_USERAUTH_PASSWD_CHANGEREQ. The meaning of these is as
- follows:
-
- SSH_MSG_USERAUTH_SUCCESS The password has been changed, and
- authentication has been successfully completed.
-
- SSH_MSG_USERAUTH_FAILURE with partial success The password has
- been changed, but more authentications are needed.
-
- SSH_MSG_USERAUTH_FAILURE without partial success The password has
- not been changed. Either password changing was not supported, or
- the old password was bad. Note that if the server has already
- sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, we know that it supports
- changing the password.
-
- SSH_MSG_USERAUTH_CHANGEREQ The password was not changed because
- the new password was not acceptable (e.g. too easy to guess).
-
- The following method-specific message numbers are used by the
- password authentication method.
-
- #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
-
-
-3.5 Host-Based Authentication: hostbased
-
- Some sites wish to allow authentication based on the host where the
- user is coming from, and the user name on the remote host. While
- this form of authentication is not suitable for high-security sites,
- it can be very convenient in many environments. This form of
- authentication is OPTIONAL. When used, special care SHOULD be taken
- to prevent a regular user from obtaining the private host key.
-
- The client requests this form of authentication by sending the
- following message. It is similar to the UNIX "rhosts" and
- "hosts.equiv" styles of authentication, except that the identity of
- the client host is checked more rigorously.
-
- This method works by having the client send a signature created with
- the private key of the client host, which the server checks with that
- host's public key. Once the client host's identity is established,
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 11]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- authorization (but no further authentication) is performed based on
- the user names on the server and the client, and the client host
- name.
-
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host (ISO-10646 UTF-8)
- string signature
-
- Public key algorithm names for use in "public key algorithm for host
- key" are defined in the transport layer specification. The "public
- host key for client host" may include certificates.
-
- Signature is a signature with the private host key of the following
- data, in this order:
-
- string session identifier
- byte SSH_MSG_USERAUTH_REQUEST
- string user name
- string service
- string "hostbased"
- string public key algorithm for host key
- string public host key and certificates for client host
- string client host name (FQDN; US-ASCII)
- string user name on the client host(ISO-10646 UTF-8)
-
- The server MUST verify that the host key actually belongs to the
- client host named in the message, that the given user on that host is
- allowed to log in, and that the signature is a valid signature on the
- appropriate value by the given host key. The server MAY ignore the
- client user name, if it wants to authenticate only the client host.
-
- It is RECOMMENDED that whenever possible, the server perform
- additional checks to verify that the network address obtained from
- the (untrusted) network matches the given client host name. This
- makes exploiting compromised host keys more difficult. Note that
- this may require special handling for connections coming through a
- firewall.
-
-4. Security Considerations
-
- The purpose of this protocol is to perform client user
- authentication. It assumed that this runs over a secure transport
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 12]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- layer protocol, which has already authenticated the server machine,
- established an encrypted communications channel, and computed a
- unique session identifier for this session. The transport layer
- provides forward secrecy for password authentication and other
- methods that rely on secret data.
-
- Full security considerations for this protocol are provided in
- Section 8 of [SSH-ARCH]
-
-Normative
-
- [SSH-ARCH]
- Ylonen, T., "SSH Protocol Architecture", I-D
- draft-ietf-architecture-15.txt, Oct 2003.
-
- [SSH-TRANS]
- Ylonen, T., "SSH Transport Layer Protocol", I-D
- draft-ietf-transport-17.txt, Oct 2003.
-
- [SSH-USERAUTH]
- Ylonen, T., "SSH Authentication Protocol", I-D
- draft-ietf-userauth-18.txt, Oct 2003.
-
- [SSH-CONNECT]
- Ylonen, T., "SSH Connection Protocol", I-D
- draft-ietf-connect-18.txt, Oct 2003.
-
- [SSH-NUMBERS]
- Lehtinen, S. and D. Moffat, "SSH Protocol Assigned
- Numbers", I-D draft-ietf-secsh-assignednumbers-05.txt, Oct
- 2003.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-Informative
-
- [RFC3066] Alvestrand, H., "Tags for the Identification of
- Languages", BCP 47, RFC 3066, January 2001.
-
- [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", RFC 2279, January 1998.
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 13]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Authors' Addresses
-
- Tatu Ylonen
- SSH Communications Security Corp
- Fredrikinkatu 42
- HELSINKI FIN-00100
- Finland
-
-
-
- Darren J. Moffat (editor)
- Sun Microsystems, Inc
- 17 Network Circle
- Menlo Park 95025
- USA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 14]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
-Intellectual Property Statement
-
- The IETF takes no position regarding the validity or scope of any
- intellectual property or other rights that might be claimed to
- pertain to the implementation or use of the technology described in
- this document or the extent to which any license under such rights
- might or might not be available; neither does it represent that it
- has made any effort to identify any such rights. Information on the
- IETF's procedures with respect to rights in standards-track and
- standards-related documentation can be found in BCP-11. Copies of
- claims of rights made available for publication and any assurances of
- licenses to be made available, or the result of an attempt made to
- obtain a general license or permission for the use of such
- proprietary rights by implementors or users of this specification can
- be obtained from the IETF Secretariat.
-
- The IETF invites any interested party to bring to its attention any
- copyrights, patents or patent applications, or other proprietary
- rights which may cover technology that may be required to practice
- this standard. Please address the information to the IETF Executive
- Director.
-
- The IETF has been notified of intellectual property rights claimed in
- regard to some or all of the specification contained in this
- document. For more information consult the online list of claimed
- rights.
-
-
-Full Copyright Statement
-
- Copyright (C) The Internet Society (2002). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assignees.
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 15]
-
-Internet-Draft SSH Authentication Protocol September 2002
-
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-Acknowledgment
-
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ylonen & Moffat Expires March 2, 2003 [Page 16] \ No newline at end of file
diff --git a/lib/ssh/examples/Makefile b/lib/ssh/examples/Makefile
index 9280c42076..d7d47eb3ae 100644
--- a/lib/ssh/examples/Makefile
+++ b/lib/ssh/examples/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2005-2015. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# 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
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# %CopyrightEnd%
#
diff --git a/lib/ssh/examples/ssh_device.erl b/lib/ssh/examples/ssh_device.erl
index f6be812915..17e3721541 100644
--- a/lib/ssh/examples/ssh_device.erl
+++ b/lib/ssh/examples/ssh_device.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/examples/ssh_sample_cli.erl b/lib/ssh/examples/ssh_sample_cli.erl
index 6f3092e567..2d8aa428ec 100644
--- a/lib/ssh/examples/ssh_sample_cli.erl
+++ b/lib/ssh/examples/ssh_sample_cli.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile
index 90d71107ad..b44c8eef35 100644
--- a/lib/ssh/src/Makefile
+++ b/lib/ssh/src/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2013. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# 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
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# %CopyrightEnd%
#
@@ -66,7 +67,6 @@ MODULES= \
ssh_file \
ssh_io \
ssh_info \
- ssh_math \
ssh_message \
ssh_no_io \
ssh_sftp \
@@ -75,7 +75,7 @@ MODULES= \
ssh_transport \
ssh_xfer
-PUBLIC_HRL_FILES= ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
+HRL_FILES =
ERL_FILES= \
$(MODULES:%=%.erl) \
@@ -95,7 +95,7 @@ APP_TARGET= $(EBIN)/$(APP_FILE)
APPUP_SRC= $(APPUP_FILE).src
APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
-INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl
+INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl ssh.hrl ssh_userauth.hrl ssh_xfer.hrl
# ----------------------------------------------------
# FLAGS
@@ -140,7 +140,82 @@ release_spec: opt
$(INSTALL_DATA) $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) $(APP_TARGET) \
$(APPUP_TARGET) "$(RELSYSDIR)/ebin"
$(INSTALL_DIR) "$(RELSYSDIR)/include"
- $(INSTALL_DATA) $(PUBLIC_HRL_FILES) "$(RELSYSDIR)/include"
+
release_docs_spec:
+
+deps:
+ erlc -M $(ERL_FILES) \
+ | sed 's@$(ERL_TOP)/lib@../..@g' \
+ | sed 's/\.$(EMULATOR)/\.$$\(EMULATOR\)/' \
+ | sed 's@^ssh_@$$(EBIN)/ssh_@'
+
+ssh.$(EMULATOR): ssh.erl ssh.hrl ssh_connect.hrl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/file.hrl
+$(EBIN)/ssh_sup.$(EMULATOR): ssh_sup.erl
+sshc_sup.$(EMULATOR): sshc_sup.erl
+sshd_sup.$(EMULATOR): sshd_sup.erl ssh.hrl
+$(EBIN)/ssh_connection_sup.$(EMULATOR): ssh_connection_sup.erl
+$(EBIN)/ssh_connection.$(EMULATOR): ssh_connection.erl ssh.hrl ssh_connect.hrl \
+ ssh_transport.hrl
+$(EBIN)/ssh_connection_handler.$(EMULATOR): ssh_connection_handler.erl ssh.hrl \
+ ssh_transport.hrl ssh_auth.hrl ssh_connect.hrl
+$(EBIN)/ssh_shell.$(EMULATOR): ssh_shell.erl ssh_connect.hrl
+$(EBIN)/ssh_system_sup.$(EMULATOR): ssh_system_sup.erl ssh.hrl
+$(EBIN)/ssh_subsystem_sup.$(EMULATOR): ssh_subsystem_sup.erl
+$(EBIN)/ssh_channel_sup.$(EMULATOR): ssh_channel_sup.erl
+$(EBIN)/ssh_acceptor_sup.$(EMULATOR): ssh_acceptor_sup.erl ssh.hrl
+$(EBIN)/ssh_acceptor.$(EMULATOR): ssh_acceptor.erl ssh.hrl
+$(EBIN)/ssh_app.$(EMULATOR): ssh_app.erl
+$(EBIN)/ssh_auth.$(EMULATOR): ssh_auth.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl ssh_auth.hrl ssh_transport.hrl
+$(EBIN)/ssh_bits.$(EMULATOR): ssh_bits.erl ssh.hrl
+$(EBIN)/ssh_cli.$(EMULATOR): ssh_cli.erl ssh.hrl ssh_connect.hrl
+$(EBIN)/ssh_file.$(EMULATOR): ssh_file.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/file.hrl ssh.hrl
+$(EBIN)/ssh_io.$(EMULATOR): ssh_io.erl ssh.hrl
+$(EBIN)/ssh_info.$(EMULATOR): ssh_info.erl
+$(EBIN)/ssh_message.$(EMULATOR): ssh_message.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl ssh_connect.hrl ssh_auth.hrl ssh_transport.hrl
+$(EBIN)/ssh_no_io.$(EMULATOR): ssh_no_io.erl ssh_transport.hrl
+$(EBIN)/ssh_sftp.$(EMULATOR): ssh_sftp.erl \
+ ../../kernel/include/file.hrl ssh.hrl \
+ ssh_xfer.hrl
+$(EBIN)/ssh_sftpd.$(EMULATOR): ssh_sftpd.erl \
+ ../../kernel/include/file.hrl ssh.hrl \
+ ssh_xfer.hrl
+$(EBIN)/ssh_sftpd_file.$(EMULATOR): ssh_sftpd_file.erl
+$(EBIN)/ssh_transport.$(EMULATOR): ssh_transport.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ../../kernel/include/inet.hrl \
+ ssh_transport.hrl ssh.hrl
+$(EBIN)/ssh_xfer.$(EMULATOR): ssh_xfer.erl ssh.hrl ssh_xfer.hrl
+$(EBIN)/ssh_sftpd_file_api.$(EMULATOR): ssh_sftpd_file_api.erl
+$(EBIN)/ssh_channel.$(EMULATOR): ssh_channel.erl ssh_connect.hrl
+$(EBIN)/ssh_daemon_channel.$(EMULATOR): ssh_daemon_channel.erl
+$(EBIN)/ssh_client_key_api.$(EMULATOR): ssh_client_key_api.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl
+$(EBIN)/ssh_server_key_api.$(EMULATOR): ssh_server_key_api.erl \
+ ../../public_key/include/public_key.hrl \
+ ../../public_key/include/OTP-PUB-KEY.hrl \
+ ../../public_key/include/PKCS-FRAME.hrl \
+ ssh.hrl
+
diff --git a/lib/ssh/src/ssh.app.src b/lib/ssh/src/ssh.app.src
index bc01c539e0..4a76fd9cd3 100644
--- a/lib/ssh/src/ssh.app.src
+++ b/lib/ssh/src/ssh.app.src
@@ -24,7 +24,6 @@
ssh_file,
ssh_io,
ssh_info,
- ssh_math,
ssh_no_io,
ssh_server_key_api,
ssh_sftp,
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index e76c110c04..e38cecf226 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 7ed17618e7..54f94acbdc 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -24,12 +25,16 @@
-include("ssh.hrl").
-include("ssh_connect.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include_lib("kernel/include/file.hrl").
-export([start/0, start/1, stop/0, connect/3, connect/4, close/1, connection_info/2,
channel_info/3,
daemon/1, daemon/2, daemon/3,
- stop_listener/1, stop_listener/2, stop_daemon/1, stop_daemon/2,
- shell/1, shell/2, shell/3]).
+ default_algorithms/0,
+ stop_listener/1, stop_listener/2, stop_listener/3,
+ stop_daemon/1, stop_daemon/2, stop_daemon/3,
+ shell/1, shell/2, shell/3
+ ]).
%%--------------------------------------------------------------------
-spec start() -> ok | {error, term()}.
@@ -113,9 +118,9 @@ channel_info(ConnectionRef, ChannelId, Options) ->
ssh_connection_handler:channel_info(ConnectionRef, ChannelId, Options).
%%--------------------------------------------------------------------
--spec daemon(integer()) -> {ok, pid()}.
--spec daemon(integer(), proplists:proplist()) -> {ok, pid()}.
--spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()}.
+-spec daemon(integer()) -> {ok, pid()} | {error, term()}.
+-spec daemon(integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
+-spec daemon(any | inet:ip_address(), integer(), proplists:proplist()) -> {ok, pid()} | {error, term()}.
%% Description: Starts a server listening for SSH connections
%% on the given port.
@@ -157,7 +162,9 @@ daemon(HostAddr, Port, Options0) ->
stop_listener(SysSup) ->
ssh_system_sup:stop_listener(SysSup).
stop_listener(Address, Port) ->
- ssh_system_sup:stop_listener(Address, Port).
+ stop_listener(Address, Port, ?DEFAULT_PROFILE).
+stop_listener(Address, Port, Profile) ->
+ ssh_system_sup:stop_listener(Address, Port, Profile).
%%--------------------------------------------------------------------
-spec stop_daemon(pid()) -> ok.
@@ -169,8 +176,9 @@ stop_listener(Address, Port) ->
stop_daemon(SysSup) ->
ssh_system_sup:stop_system(SysSup).
stop_daemon(Address, Port) ->
- ssh_system_sup:stop_system(Address, Port).
-
+ ssh_system_sup:stop_system(Address, Port, ?DEFAULT_PROFILE).
+stop_daemon(Address, Port, Profile) ->
+ ssh_system_sup:stop_system(Address, Port, Profile).
%%--------------------------------------------------------------------
-spec shell(string()) -> _.
-spec shell(string(), proplists:proplist()) -> _.
@@ -208,6 +216,11 @@ shell(Host, Port, Options) ->
end.
%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+default_algorithms() ->
+ ssh_transport:default_algorithms().
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
fix_idle_time(SshOptions) ->
@@ -222,11 +235,29 @@ start_daemon(Host, Port, Options, Inet) ->
{error, _Reason} = Error ->
Error;
{SocketOptions, SshOptions}->
- do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ try
+ do_start_daemon(Host, Port,[{role, server} |SshOptions] , [Inet | SocketOptions])
+ catch
+ throw:bad_fd -> {error,bad_fd};
+ _C:_E -> {error,{cannot_start_daemon,_C,_E}}
+ end
end.
-do_start_daemon(Host, Port, Options, SocketOptions) ->
- case ssh_system_sup:system_supervisor(Host, Port) of
+do_start_daemon(Host0, Port0, Options, SocketOptions) ->
+ {Host,Port} = try
+ case proplists:get_value(fd, SocketOptions) of
+ undefined ->
+ {Host0,Port0};
+ Fd when Port0==0 ->
+ find_hostport(Fd);
+ _ ->
+ {Host0,Port0}
+ end
+ catch
+ _:_ -> throw(bad_fd)
+ end,
+ Profile = proplists:get_value(profile, Options, ?DEFAULT_PROFILE),
+ case ssh_system_sup:system_supervisor(Host, Port, Profile) of
undefined ->
%% It would proably make more sense to call the
%% address option host but that is a too big change at the
@@ -258,8 +289,17 @@ do_start_daemon(Host, Port, Options, SocketOptions) ->
end
end.
+find_hostport(Fd) ->
+ %% Using internal functions inet:open/8 and inet:close/0.
+ %% Don't try this at home unless you know what you are doing!
+ {ok,S} = inet:open(Fd, {0,0,0,0}, 0, [], tcp, inet, stream, inet_tcp),
+ {ok, HostPort} = inet:sockname(S),
+ ok = inet:close(S),
+ HostPort.
+
+
handle_options(Opts) ->
- try handle_option(proplists:unfold(Opts), [], []) of
+ try handle_option(algs_compatibility(proplists:unfold(Opts)), [], []) of
{Inet, Ssh} ->
{handle_ip(Inet), Ssh}
catch
@@ -267,6 +307,30 @@ handle_options(Opts) ->
Error
end.
+
+algs_compatibility(Os0) ->
+ %% Take care of old options 'public_key_alg' and 'pref_public_key_algs'
+ case proplists:get_value(public_key_alg, Os0) of
+ undefined ->
+ Os0;
+ A when is_atom(A) ->
+ %% Skip public_key_alg if pref_public_key_algs is defined:
+ Os = lists:keydelete(public_key_alg, 1, Os0),
+ case proplists:get_value(pref_public_key_algs,Os) of
+ undefined when A == 'ssh-rsa' ; A==ssh_rsa ->
+ [{pref_public_key_algs,['ssh-rsa','ssh-dss']} | Os];
+ undefined when A == 'ssh-dss' ; A==ssh_dsa ->
+ [{pref_public_key_algs,['ssh-dss','ssh-rsa']} | Os];
+ undefined ->
+ throw({error, {eoptions, {public_key_alg,A} }});
+ _ ->
+ Os
+ end;
+ V ->
+ throw({error, {eoptions, {public_key_alg,V} }})
+ end.
+
+
handle_option([], SocketOptions, SshOptions) ->
{SocketOptions, SshOptions};
handle_option([{system_dir, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -279,8 +343,6 @@ handle_option([{silently_accept_hosts, _} = Opt | Rest], SocketOptions, SshOptio
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{user_interaction, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{public_key_alg, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{connect_timeout, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{user, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -295,11 +357,13 @@ handle_option([{user_passwords, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{pwdfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{key_cb, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{role, _} = Opt | Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([{compression, _} = Opt | Rest], SocketOptions, SshOptions) ->
+handle_option([{key_cb, {Module, Options}} | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option({key_cb, Module}),
+ handle_ssh_priv_option({key_cb_private, Options}) |
+ SshOptions]);
+handle_option([{key_cb, Module} | Rest], SocketOptions, SshOptions) ->
+ handle_option([{key_cb, {Module, []}} | Rest], SocketOptions, SshOptions);
+handle_option([{keyboard_interact_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
%%Backwards compatibility
handle_option([{allow_user_interaction, Value} | Rest], SocketOptions, SshOptions) ->
@@ -310,6 +374,8 @@ handle_option([{connectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{disconnectfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{unexpectedfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{failfun, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{ssh_msg_debug_fun, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -335,6 +401,12 @@ handle_option([{auth_method_kb_interactive_data, _} = Opt | Rest], SocketOptions
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{pref_public_key_algs, _} = Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{preferred_algorithms,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{dh_gex_groups,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{dh_gex_limits,_} = Opt | Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{quiet_mode, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) ->
@@ -343,16 +415,23 @@ handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{max_sessions, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_channels, _} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{parallel_login, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
-handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
- handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
+%% (Is handled by proplists:unfold above:)
+%% handle_option([parallel_login|Rest], SocketOptions, SshOptions) ->
+%% handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]);
handle_option([{minimal_remote_max_packet_size, _} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([{id_string, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{profile, _ID} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
+handle_option([{max_random_length_padding, _Bool} = Opt|Rest], SocketOptions, SshOptions) ->
+ handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]);
handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions).
@@ -360,25 +439,83 @@ handle_option([Opt | Rest], SocketOptions, SshOptions) ->
handle_ssh_option({minimal_remote_max_packet_size, Value} = Opt) when is_integer(Value), Value >=0 ->
Opt;
handle_ssh_option({system_dir, Value} = Opt) when is_list(Value) ->
- Opt;
+ check_dir(Opt);
handle_ssh_option({user_dir, Value} = Opt) when is_list(Value) ->
- Opt;
+ check_dir(Opt);
handle_ssh_option({user_dir_fun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_boolean(Value) ->
Opt;
handle_ssh_option({user_interaction, Value} = Opt) when is_boolean(Value) ->
Opt;
-handle_ssh_option({public_key_alg, ssh_dsa}) ->
- {public_key_alg, 'ssh-dss'};
-handle_ssh_option({public_key_alg, ssh_rsa}) ->
- {public_key_alg, 'ssh-rsa'};
-handle_ssh_option({public_key_alg, Value} = Opt) when Value == 'ssh-rsa'; Value == 'ssh-dss' ->
+handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
+ handle_pref_algs(Opt);
+
+handle_ssh_option({dh_gex_groups,L0}) when is_list(L0) ->
+ {dh_gex_groups,
+ collect_per_size(
+ lists:foldl(
+ fun({N,G,P}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,{G,P}}, Acc) when is_integer(N),N>0,
+ is_integer(G),G>0,
+ is_integer(P),P>0 ->
+ [{N,{G,P}} | Acc];
+ ({N,GPs}, Acc) when is_list(GPs) ->
+ lists:foldr(fun({Gi,Pi}, Acci) when is_integer(Gi),Gi>0,
+ is_integer(Pi),Pi>0 ->
+ [{N,{Gi,Pi}} | Acci]
+ end, Acc, GPs)
+ end, [], L0))};
+
+handle_ssh_option({dh_gex_groups,{Tag,File=[C|_]}}=Opt) when is_integer(C), C>0,
+ Tag == file ;
+ Tag == ssh_moduli_file ->
+ {ok,GroupDefs} =
+ case Tag of
+ file ->
+ file:consult(File);
+ ssh_moduli_file ->
+ case file:open(File,[read]) of
+ {ok,D} ->
+ try
+ {ok,Moduli} = read_moduli_file(D, 1, []),
+ file:close(D),
+ {ok, Moduli}
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file "++File}})
+ end;
+ {error,enoent} ->
+ throw({error, {{eoptions, Opt}, "File not found:"++File}});
+ {error,Error} ->
+ throw({error, {{eoptions, Opt}, io_lib:format("Error reading file ~s: ~p",[File,Error])}})
+ end
+ end,
+
+ try
+ handle_ssh_option({dh_gex_groups,GroupDefs})
+ catch
+ _:_ ->
+ throw({error, {{eoptions, Opt}, "Bad format in file: "++File}})
+ end;
+
+
+handle_ssh_option({dh_gex_limits,{Min,Max}} = Opt) when is_integer(Min), Min>0,
+ is_integer(Max), Max>=Min ->
+ %% Server
+ Opt;
+handle_ssh_option({dh_gex_limits,{Min,I,Max}} = Opt) when is_integer(Min), Min>0,
+ is_integer(I), I>=Min,
+ is_integer(Max), Max>=I ->
+ %% Client
Opt;
handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), length(Value) >= 1 ->
- case handle_pref_algs(Value, []) of
+ case handle_user_pref_pubkey_algs(Value, []) of
{true, NewOpts} ->
- NewOpts;
+ {pref_public_key_algs, NewOpts};
_ ->
throw({error, {eoptions, Opt}})
end;
@@ -386,6 +523,8 @@ handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value
Opt;
handle_ssh_option({max_sessions, Value} = Opt) when is_integer(Value), Value>0 ->
Opt;
+handle_ssh_option({max_channels, Value} = Opt) when is_integer(Value), Value>0 ->
+ Opt;
handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity ->
Opt;
handle_ssh_option({parallel_login, Value} = Opt) when Value==true ; Value==false ->
@@ -400,10 +539,17 @@ handle_ssh_option({password, Value} = Opt) when is_list(Value) ->
Opt;
handle_ssh_option({user_passwords, Value} = Opt) when is_list(Value)->
Opt;
-handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value) ->
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,2) ->
+ Opt;
+handle_ssh_option({pwdfun, Value} = Opt) when is_function(Value,4) ->
Opt;
handle_ssh_option({key_cb, Value} = Opt) when is_atom(Value) ->
Opt;
+handle_ssh_option({key_cb, {CallbackMod, CallbackOptions}} = Opt) when is_atom(CallbackMod),
+ is_list(CallbackOptions) ->
+ Opt;
+handle_ssh_option({keyboard_interact_fun, Value} = Opt) when is_function(Value,3) ->
+ Opt;
handle_ssh_option({compression, Value} = Opt) when is_atom(Value) ->
Opt;
handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module),
@@ -424,7 +570,9 @@ handle_ssh_option({infofun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({connectfun, Value} = Opt) when is_function(Value) ->
Opt;
-handle_ssh_option({disconnectfun , Value} = Opt) when is_function(Value) ->
+handle_ssh_option({disconnectfun, Value} = Opt) when is_function(Value) ->
+ Opt;
+handle_ssh_option({unexpectedfun, Value} = Opt) when is_function(Value,2) ->
Opt;
handle_ssh_option({failfun, Value} = Opt) when is_function(Value) ->
Opt;
@@ -458,9 +606,17 @@ handle_ssh_option({id_string, random}) ->
{id_string, {random,2,5}}; %% 2 - 5 random characters
handle_ssh_option({id_string, ID} = Opt) when is_list(ID) ->
Opt;
+handle_ssh_option({max_random_length_padding, Value} = Opt) when is_integer(Value),
+ Value =< 255 ->
+ Opt;
+handle_ssh_option({profile, Value} = Opt) when is_atom(Value) ->
+ Opt;
handle_ssh_option(Opt) ->
throw({error, {eoptions, Opt}}).
+handle_ssh_priv_option({key_cb_private, Value} = Opt) when is_list(Value) ->
+ Opt.
+
handle_inet_option({active, _} = Opt) ->
throw({error, {{eoptions, Opt}, "SSH has built in flow control, "
"and active is handled internally, user is not allowed"
@@ -474,23 +630,83 @@ handle_inet_option({reuseaddr, _} = Opt) ->
%% Option verified by inet
handle_inet_option(Opt) ->
Opt.
+
+
%% Check preferred algs
-handle_pref_algs([], Acc) ->
- {true, lists:reverse(Acc)};
-handle_pref_algs([H|T], Acc) ->
- case H of
- ssh_dsa ->
- handle_pref_algs(T, ['ssh-dss'| Acc]);
- ssh_rsa ->
- handle_pref_algs(T, ['ssh-rsa'| Acc]);
- 'ssh-dss' ->
- handle_pref_algs(T, ['ssh-dss'| Acc]);
- 'ssh-rsa' ->
- handle_pref_algs(T, ['ssh-rsa'| Acc]);
- _ ->
- false
+
+handle_pref_algs({preferred_algorithms,Algs}) ->
+ try alg_duplicates(Algs, [], []) of
+ [] ->
+ {preferred_algorithms,
+ [try ssh_transport:supported_algorithms(Key)
+ of
+ DefAlgs -> handle_pref_alg(Key,Vals,DefAlgs)
+ catch
+ _:_ -> throw({error, {{eoptions, {preferred_algorithms,Key}},
+ "Bad preferred_algorithms key"}})
+ end || {Key,Vals} <- Algs]
+ };
+
+ Dups ->
+ throw({error, {{eoptions, {preferred_algorithms,Dups}}, "Duplicates found"}})
+ catch
+ _:_ ->
+ throw({error, {{eoptions, preferred_algorithms}, "Malformed"}})
end.
+alg_duplicates([{K,V}|KVs], Ks, Dups0) ->
+ Dups =
+ case lists:member(K,Ks) of
+ true ->
+ [K|Dups0];
+ false ->
+ Dups0
+ end,
+ case V--lists:usort(V) of
+ [] ->
+ alg_duplicates(KVs, [K|Ks], Dups);
+ Ds ->
+ alg_duplicates(KVs, [K|Ks], Dups++Ds)
+ end;
+alg_duplicates([], _Ks, Dups) ->
+ Dups.
+
+handle_pref_alg(Key,
+ Vs=[{client2server,C2Ss=[_|_]},{server2client,S2Cs=[_|_]}],
+ [{client2server,Sup_C2Ss},{server2client,Sup_S2Cs}]
+ ) ->
+ chk_alg_vs(Key, C2Ss, Sup_C2Ss),
+ chk_alg_vs(Key, S2Cs, Sup_S2Cs),
+ {Key, Vs};
+
+handle_pref_alg(Key,
+ Vs=[{server2client,[_|_]},{client2server,[_|_]}],
+ Sup=[{client2server,_},{server2client,_}]
+ ) ->
+ handle_pref_alg(Key, lists:reverse(Vs), Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[{client2server,_},{server2client,_}]
+ ) when is_atom(V) ->
+ handle_pref_alg(Key, [{client2server,Vs},{server2client,Vs}], Sup);
+
+handle_pref_alg(Key,
+ Vs=[V|_],
+ Sup=[S|_]
+ ) when is_atom(V), is_atom(S) ->
+ chk_alg_vs(Key, Vs, Sup),
+ {Key, Vs};
+
+handle_pref_alg(Key, Vs, _) ->
+ throw({error, {{eoptions, {preferred_algorithms,[{Key,Vs}]}}, "Badly formed list"}}).
+
+chk_alg_vs(OptKey, Values, SupportedValues) ->
+ case (Values -- SupportedValues) of
+ [] -> Values;
+ Bad -> throw({error, {{eoptions, {OptKey,Bad}}, "Unsupported value(s) found"}})
+ end.
+
handle_ip(Inet) -> %% Default to ipv4
case lists:member(inet, Inet) of
true ->
@@ -503,4 +719,74 @@ handle_ip(Inet) -> %% Default to ipv4
[inet | Inet]
end
end.
-
+
+check_dir({_,Dir} = Opt) ->
+ case directory_exist_readable(Dir) of
+ ok ->
+ Opt;
+ {error,Error} ->
+ throw({error, {eoptions,{Opt,Error}}})
+ end.
+
+directory_exist_readable(Dir) ->
+ case file:read_file_info(Dir) of
+ {ok, #file_info{type = directory,
+ access = Access}} ->
+ case Access of
+ read -> ok;
+ read_write -> ok;
+ _ -> {error, eacces}
+ end;
+
+ {ok, #file_info{}}->
+ {error, enotdir};
+
+ {error, Error} ->
+ {error, Error}
+ end.
+
+
+
+collect_per_size(L) ->
+ lists:foldr(
+ fun({Sz,GP}, [{Sz,GPs}|Acc]) -> [{Sz,[GP|GPs]}|Acc];
+ ({Sz,GP}, Acc) -> [{Sz,[GP]}|Acc]
+ end, [], lists:sort(L)).
+
+read_moduli_file(D, I, Acc) ->
+ case io:get_line(D,"") of
+ {error,Error} ->
+ {error,Error};
+ eof ->
+ {ok, Acc};
+ "#" ++ _ -> read_moduli_file(D, I+1, Acc);
+ <<"#",_/binary>> -> read_moduli_file(D, I+1, Acc);
+ Data ->
+ Line = if is_binary(Data) -> binary_to_list(Data);
+ is_list(Data) -> Data
+ end,
+ try
+ [_Time,_Type,_Tests,_Tries,Size,G,P] = string:tokens(Line," \r\n"),
+ M = {list_to_integer(Size),
+ {list_to_integer(G), list_to_integer(P,16)}
+ },
+ read_moduli_file(D, I+1, [M|Acc])
+ catch
+ _:_ ->
+ read_moduli_file(D, I+1, Acc)
+ end
+ end.
+
+handle_user_pref_pubkey_algs([], Acc) ->
+ {true, lists:reverse(Acc)};
+handle_user_pref_pubkey_algs([H|T], Acc) ->
+ case lists:member(H, ?SUPPORTED_USER_KEYS) of
+ true ->
+ handle_user_pref_pubkey_algs(T, [H| Acc]);
+
+ false when H==ssh_dsa -> handle_user_pref_pubkey_algs(T, ['ssh-dss'| Acc]);
+ false when H==ssh_rsa -> handle_user_pref_pubkey_algs(T, ['ssh-rsa'| Acc]);
+
+ false ->
+ false
+ end.
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 0c4d34f89c..f88098819d 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -28,20 +29,26 @@
-define(SSH_DEFAULT_PORT, 22).
-define(SSH_MAX_PACKET_SIZE, (256*1024)).
--define(SSH_LENGHT_INDICATOR_SIZE, 4).
-define(REKEY_TIMOUT, 3600000).
-define(REKEY_DATA_TIMOUT, 60000).
+-define(DEFAULT_PROFILE, default).
+
+-define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
+-define(SUPPORTED_USER_KEYS, ['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521']).
-define(FALSE, 0).
-define(TRUE, 1).
%% basic binary constructors
--define(BOOLEAN(X), X:8/unsigned-big-integer).
--define(BYTE(X), X:8/unsigned-big-integer).
--define(UINT16(X), X:16/unsigned-big-integer).
--define(UINT32(X), X:32/unsigned-big-integer).
--define(UINT64(X), X:64/unsigned-big-integer).
+-define(BOOLEAN(X), (X):8/unsigned-big-integer).
+-define(BYTE(X), (X):8/unsigned-big-integer).
+-define(UINT16(X), (X):16/unsigned-big-integer).
+-define(UINT32(X), (X):32/unsigned-big-integer).
+-define(UINT64(X), (X):64/unsigned-big-integer).
-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+-define(DEC_BIN(X,Len), ?UINT32(Len), X:Len/binary ).
+-define(DEC_MPINT(I,Len), ?UINT32(Len), I:Len/big-signed-integer-unit:8 ).
+
%% building macros
-define(boolean(X),
case X of
@@ -122,15 +129,18 @@
recv_sequence = 0,
keyex_key,
keyex_info,
+ random_length_padding = 255, % From RFC 4253 section 6.
%% User auth
user,
service,
userauth_quiet_mode, % boolean()
- userauth_supported_methods , %
- userauth_methods,
+ userauth_supported_methods, % string() eg "keyboard-interactive,password"
+ userauth_methods, % list( string() ) eg ["keyboard-interactive", "password"]
+ kb_tries_left = 0, % integer(), num tries left for "keyboard-interactive"
userauth_preference,
available_host_keys,
+ pwdfun_user_state,
authenticated = false
}).
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 34988f17b6..d94dedf1bf 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -21,6 +22,8 @@
-module(ssh_acceptor).
+-include("ssh.hrl").
+
%% Internal application API
-export([start_link/5,
number_of_connections/1]).
@@ -53,7 +56,12 @@ acceptor_init(Parent, Port, Address, SockOpts, Opts, AcceptTimeout) ->
error
end.
-do_socket_listen(Callback, Port, Opts) ->
+do_socket_listen(Callback, Port0, Opts) ->
+ Port =
+ case proplists:get_value(fd, Opts) of
+ undefined -> Port0;
+ _ -> 0
+ end,
case Callback:listen(Port, Opts) of
{error, nxdomain} ->
Callback:listen(Port, lists:delete(inet6, Opts));
@@ -82,8 +90,10 @@ acceptor_loop(Callback, Port, Address, Opts, ListenSocket, AcceptTimeout) ->
end.
handle_connection(Callback, Address, Port, Options, Socket) ->
- SystemSup = ssh_system_sup:system_supervisor(Address, Port),
SSHopts = proplists:get_value(ssh_opts, Options, []),
+ Profile = proplists:get_value(profile, SSHopts, ?DEFAULT_PROFILE),
+ SystemSup = ssh_system_sup:system_supervisor(Address, Port, Profile),
+
MaxSessions = proplists:get_value(max_sessions,SSHopts,infinity),
case number_of_connections(SystemSup) < MaxSessions of
true ->
diff --git a/lib/ssh/src/ssh_acceptor_sup.erl b/lib/ssh/src/ssh_acceptor_sup.erl
index 46fdef07d0..a3dc64850f 100644
--- a/lib/ssh/src/ssh_acceptor_sup.erl
+++ b/lib/ssh/src/ssh_acceptor_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -26,7 +27,9 @@
-module(ssh_acceptor_sup).
-behaviour(supervisor).
--export([start_link/1, start_child/2, stop_child/3]).
+-include("ssh.hrl").
+
+-export([start_link/1, start_child/2, stop_child/4]).
%% Supervisor callback
-export([init/1]).
@@ -45,14 +48,16 @@ start_child(AccSup, ServerOpts) ->
{error, already_present} ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- stop_child(AccSup, Address, Port),
+ Profile = proplists:get_value(profile,
+ proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ stop_child(AccSup, Address, Port, Profile),
supervisor:start_child(AccSup, Spec);
Reply ->
Reply
end.
-stop_child(AccSup, Address, Port) ->
- Name = id(Address, Port),
+stop_child(AccSup, Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
case supervisor:terminate_child(AccSup, Name) of
ok ->
supervisor:delete_child(AccSup, Name);
@@ -77,7 +82,8 @@ child_spec(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
Timeout = proplists:get_value(timeout, ServerOpts, ?DEFAULT_TIMEOUT),
- Name = id(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(Address, Port, Profile),
SocketOpts = proplists:get_value(socket_opts, ServerOpts),
StartFunc = {ssh_acceptor, start_link, [Port, Address,
[{active, false},
@@ -89,6 +95,11 @@ child_spec(ServerOpts) ->
Type = worker,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Address, Port) ->
- {ssh_acceptor_sup, Address, Port}.
+id(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {ssh_acceptor_sup, any, Port, Profile};
+ false ->
+ {ssh_acceptor_sup, Address, Port, Profile}
+ end.
diff --git a/lib/ssh/src/ssh_app.erl b/lib/ssh/src/ssh_app.erl
index 38659b1a2d..1a11938dd9 100644
--- a/lib/ssh/src/ssh_app.erl
+++ b/lib/ssh/src/ssh_app.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 9d1ab14ce9..b71bed033a 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -40,27 +41,29 @@ publickey_msg([Alg, #ssh{user = User,
session_id = SessionId,
service = Service,
opts = Opts} = Ssh]) ->
-
Hash = sha, %% Maybe option?!
KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
-
case KeyCb:user_key(Alg, Opts) of
- {ok, Key} ->
- StrAlgo = algorithm_string(Alg),
- PubKeyBlob = encode_public_key(Key),
- SigData = build_sig_data(SessionId,
- User, Service, PubKeyBlob, StrAlgo),
- Sig = ssh_transport:sign(SigData, Hash, Key),
- SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
- ssh_transport:ssh_packet(
- #ssh_msg_userauth_request{user = User,
- service = Service,
- method = "publickey",
- data = [?TRUE,
- ?string(StrAlgo),
- ?binary(PubKeyBlob),
- ?binary(SigBlob)]},
- Ssh);
+ {ok, PrivKey} ->
+ StrAlgo = atom_to_list(Alg),
+ case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of
+ not_ok ->
+ not_ok;
+ PubKeyBlob ->
+ SigData = build_sig_data(SessionId,
+ User, Service, PubKeyBlob, StrAlgo),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
+ SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_request{user = User,
+ service = Service,
+ method = "publickey",
+ data = [?TRUE,
+ ?string(StrAlgo),
+ ?binary(PubKeyBlob),
+ ?binary(SigBlob)]},
+ Ssh)
+ end;
_Error ->
not_ok
end.
@@ -115,33 +118,21 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) ->
service = "ssh-connection",
method = "none",
data = <<>>},
- case proplists:get_value(pref_public_key_algs, Opts, false) of
- false ->
- FirstAlg = proplists:get_value(public_key_alg, Opts, ?PREFERRED_PK_ALG),
- SecondAlg = other_alg(FirstAlg),
- Prefs = method_preference(FirstAlg, SecondAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"});
- Algs ->
- FirstAlg = lists:nth(1, Algs),
- case length(Algs) =:= 2 of
- true ->
- SecondAlg = other_alg(FirstAlg),
- Prefs = method_preference(FirstAlg, SecondAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"});
- _ ->
- Prefs = method_preference(FirstAlg),
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- userauth_preference = Prefs,
- userauth_methods = none,
- service = "ssh-connection"})
- end
- end;
+ Algs0 = proplists:get_value(pref_public_key_algs, Opts, ?SUPPORTED_USER_KEYS),
+ %% The following line is not strictly correct. The call returns the
+ %% supported HOST key types while we are interested in USER keys. However,
+ %% they "happens" to be the same (for now). This could change....
+ %% There is no danger as long as the set of user keys is a subset of the set
+ %% of host keys.
+ CryptoSupported = ssh_transport:supported_algorithms(public_key),
+ Algs = [A || A <- Algs0,
+ lists:member(A, CryptoSupported)],
+
+ Prefs = method_preference(Algs),
+ ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
+ userauth_preference = Prefs,
+ userauth_methods = none,
+ service = "ssh-connection"});
{error, no_user} ->
ErrStr = "Could not determine the users name",
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_ILLEGAL_USER_NAME,
@@ -168,7 +159,7 @@ userauth_request_msg(#ssh{userauth_methods = Methods,
not_ok ->
userauth_request_msg(Ssh);
Result ->
- Result
+ {Pref,Result}
end;
false ->
userauth_request_msg(Ssh)
@@ -185,17 +176,18 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "password",
data = <<?FALSE, ?UINT32(Sz), BinPwd:Sz/binary>>}, _,
- #ssh{opts = Opts} = Ssh) ->
+ #ssh{opts = Opts,
+ userauth_supported_methods = Methods} = Ssh) ->
Password = unicode:characters_to_list(BinPwd),
- case check_password(User, Password, Opts) of
- true ->
+ case check_password(User, Password, Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
- partial_success = false}, Ssh)}
+ authentications = Methods,
+ partial_success = false}, Ssh1)}
end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -207,7 +199,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
%% ?UINT32(Sz2), NewBinPwd:Sz2/binary
>>
}, _,
- Ssh) ->
+ #ssh{userauth_supported_methods = Methods} = Ssh) ->
%% Password change without us having sent SSH_MSG_USERAUTH_PASSWD_CHANGEREQ (because we never do)
%% RFC 4252 says:
%% SSH_MSG_USERAUTH_FAILURE without partial success - The password
@@ -216,7 +208,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
{not_authorized, {User, {error,"Password change not supported"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
+ authentications = Methods,
partial_success = false}, Ssh)};
handle_userauth_request(#ssh_msg_userauth_request{user = User,
@@ -232,7 +224,9 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "publickey",
data = Data},
- SessionId, #ssh{opts = Opts} = Ssh) ->
+ SessionId,
+ #ssh{opts = Opts,
+ userauth_supported_methods = Methods} = Ssh) ->
<<?BYTE(HaveSig), ?UINT32(ALen), BAlg:ALen/binary,
?UINT32(KLen), KeyBlob:KLen/binary, SigWLen/binary>> = Data,
Alg = binary_to_list(BAlg),
@@ -247,7 +241,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
false ->
{not_authorized, {User, undefined},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications="publickey,password",
+ authentications = Methods,
partial_success = false}, Ssh)}
end;
?FALSE ->
@@ -261,49 +255,59 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
method = "keyboard-interactive",
data = _},
- _, #ssh{opts = Opts} = Ssh) ->
- %% RFC4256
- %% The data field contains:
- %% - language tag (deprecated). If =/=[] SHOULD use it however. We skip
- %% it for simplicity.
- %% - submethods. "... the user can give a hint of which actual methods
- %% he wants to use. ...". It's a "MAY use" so we skip
- %% it. It also needs an understanding between the client
- %% and the server.
- %%
- %% "The server MUST reply with an SSH_MSG_USERAUTH_SUCCESS,
- %% SSH_MSG_USERAUTH_FAILURE, or SSH_MSG_USERAUTH_INFO_REQUEST message."
- Default = {"SSH server",
- "Enter password for \""++User++"\"",
- "pwd: ",
- false},
-
- {Name, Instruction, Prompt, Echo} =
- case proplists:get_value(auth_method_kb_interactive_data, Opts) of
- undefined ->
- Default;
- {_,_,_,_}=V ->
- V;
- F when is_function(F) ->
- {_,PeerName} = Ssh#ssh.peer,
- F(PeerName, User, "ssh-connection")
- end,
- EchoEnc = case Echo of
- true -> <<?TRUE>>;
- false -> <<?FALSE>>
- end,
- Msg = #ssh_msg_userauth_info_request{name = unicode:characters_to_list(Name),
- instruction = unicode:characters_to_list(Instruction),
- language_tag = "",
- num_prompts = 1,
- data = <<?STRING(unicode:characters_to_binary(Prompt)),
- EchoEnc/binary
- >>
- },
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User,
- opts = [{max_kb_tries,3},{kb_userauth_info_msg,Msg}|Opts]
- })};
+ _, #ssh{opts = Opts,
+ kb_tries_left = KbTriesLeft,
+ userauth_supported_methods = Methods} = Ssh) ->
+ case KbTriesLeft of
+ N when N<1 ->
+ {not_authorized, {User, {authmethod, "keyboard-interactive"}},
+ ssh_transport:ssh_packet(
+ #ssh_msg_userauth_failure{authentications = Methods,
+ partial_success = false}, Ssh)};
+
+ _ ->
+ %% RFC4256
+ %% The data field contains:
+ %% - language tag (deprecated). If =/=[] SHOULD use it however. We skip
+ %% it for simplicity.
+ %% - submethods. "... the user can give a hint of which actual methods
+ %% he wants to use. ...". It's a "MAY use" so we skip
+ %% it. It also needs an understanding between the client
+ %% and the server.
+ %%
+ %% "The server MUST reply with an SSH_MSG_USERAUTH_SUCCESS,
+ %% SSH_MSG_USERAUTH_FAILURE, or SSH_MSG_USERAUTH_INFO_REQUEST message."
+ Default = {"SSH server",
+ "Enter password for \""++User++"\"",
+ "password: ",
+ false},
+
+ {Name, Instruction, Prompt, Echo} =
+ case proplists:get_value(auth_method_kb_interactive_data, Opts) of
+ undefined ->
+ Default;
+ {_,_,_,_}=V ->
+ V;
+ F when is_function(F) ->
+ {_,PeerName} = Ssh#ssh.peer,
+ F(PeerName, User, "ssh-connection")
+ end,
+ EchoEnc = case Echo of
+ true -> <<?TRUE>>;
+ false -> <<?FALSE>>
+ end,
+ Msg = #ssh_msg_userauth_info_request{name = unicode:characters_to_list(Name),
+ instruction = unicode:characters_to_list(Instruction),
+ language_tag = "",
+ num_prompts = 1,
+ data = <<?STRING(unicode:characters_to_binary(Prompt)),
+ EchoEnc/binary
+ >>
+ },
+ {not_authorized, {User, undefined},
+ ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User
+ })}
+ end;
handle_userauth_request(#ssh_msg_userauth_request{user = User,
service = "ssh-connection",
@@ -314,6 +318,8 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
#ssh_msg_userauth_failure{authentications = Methods,
partial_success = false}, Ssh)}.
+
+
handle_userauth_info_request(
#ssh_msg_userauth_info_request{name = Name,
instruction = Instr,
@@ -330,33 +336,20 @@ handle_userauth_info_request(
handle_userauth_info_response(#ssh_msg_userauth_info_response{num_responses = 1,
data = <<?UINT32(Sz), Password:Sz/binary>>},
- #ssh{opts = Opts0,
- user = User} = Ssh) ->
- NumTriesLeft = proplists:get_value(max_kb_tries, Opts0, 0) - 1,
- Opts = lists:keydelete(max_kb_tries,1,Opts0),
- case check_password(User, unicode:characters_to_list(Password), Opts) of
- true ->
+ #ssh{opts = Opts,
+ kb_tries_left = KbTriesLeft,
+ user = User,
+ userauth_supported_methods = Methods} = Ssh) ->
+ case check_password(User, unicode:characters_to_list(Password), Opts, Ssh) of
+ {true,Ssh1} ->
{authorized, User,
- ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh)};
- false when NumTriesLeft > 0 ->
- UserAuthInfoMsg =
- (proplists:get_value(kb_userauth_info_msg,Opts))
- #ssh_msg_userauth_info_request{name = "",
- instruction =
- lists:concat(
- ["Bad user or password, try again. ",
- integer_to_list(NumTriesLeft),
- " tries left."])},
- {not_authorized, {User, undefined},
- ssh_transport:ssh_packet(UserAuthInfoMsg,
- Ssh#ssh{opts = [{max_kb_tries,NumTriesLeft}|Opts]})};
-
- false ->
+ ssh_transport:ssh_packet(#ssh_msg_userauth_success{}, Ssh1)};
+ {false,Ssh1} ->
{not_authorized, {User, {error,"Bad user or password"}},
ssh_transport:ssh_packet(#ssh_msg_userauth_failure{
- authentications = "",
+ authentications = Methods,
partial_success = false},
- Ssh#ssh{opts = lists:keydelete(kb_userauth_info_msg,1,Opts)}
+ Ssh1#ssh{kb_tries_left = max(KbTriesLeft-1, 0)}
)}
end;
@@ -367,20 +360,23 @@ handle_userauth_info_response(#ssh_msg_userauth_info_response{},
"keyboard-interactive",
language = "en"}).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-method_preference(Alg1, Alg2) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"publickey", ?MODULE, publickey_msg,[Alg2]},
- {"password", ?MODULE, password_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ].
-method_preference(Alg1) ->
- [{"publickey", ?MODULE, publickey_msg, [Alg1]},
- {"password", ?MODULE, password_msg, []},
- {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
- ].
+method_preference(Algs) ->
+ lists:foldr(fun(A, Acc) ->
+ [{"publickey", ?MODULE, publickey_msg, [A]} | Acc]
+ end,
+ [{"password", ?MODULE, password_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []},
+ {"keyboard-interactive", ?MODULE, keyboard_interactive_msg, []}
+ ],
+ Algs).
user_name(Opts) ->
Env = case os:type() of
@@ -401,13 +397,34 @@ user_name(Opts) ->
{ok, User}
end.
-check_password(User, Password, Opts) ->
+check_password(User, Password, Opts, Ssh) ->
case proplists:get_value(pwdfun, Opts) of
undefined ->
Static = get_password_option(Opts, User),
- Password == Static;
- Cheker ->
- Cheker(User, Password)
+ {Password == Static, Ssh};
+
+ Checker when is_function(Checker,2) ->
+ {Checker(User, Password), Ssh};
+
+ Checker when is_function(Checker,4) ->
+ #ssh{pwdfun_user_state = PrivateState,
+ peer = {_,PeerAddr={_,_}}
+ } = Ssh,
+ case Checker(User, Password, PeerAddr, PrivateState) of
+ true ->
+ {true,Ssh};
+ false ->
+ {false,Ssh};
+ {true,NewState} ->
+ {true, Ssh#ssh{pwdfun_user_state=NewState}};
+ {false,NewState} ->
+ {false, Ssh#ssh{pwdfun_user_state=NewState}};
+ disconnect ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
+ description =
+ "Unable to connect using the available authentication methods",
+ language = ""})
+ end
end.
get_password_option(Opts, User) ->
@@ -444,10 +461,7 @@ build_sig_data(SessionId, User, Service, KeyBlob, Alg) ->
?binary(KeyBlob)],
list_to_binary(Sig).
-algorithm_string('ssh-rsa') ->
- "ssh-rsa";
-algorithm_string('ssh-dss') ->
- "ssh-dss".
+
decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
ssh_message:decode_keyboard_interactive_prompts(Data, []).
@@ -463,19 +477,19 @@ keyboard_interact_get_responses(_, undefined, Password, _, _, _, _, _,
1) when Password =/= undefined ->
[Password]; %% Password auth implemented with keyboard-interaction and passwd is known
keyboard_interact_get_responses(_, _, _, _, _, _, _, _, 0) ->
- [""];
+ [];
keyboard_interact_get_responses(false, undefined, undefined, _, _, _, [Prompt|_], Opts, _) ->
ssh_no_io:read_line(Prompt, Opts); %% Throws error as keyboard interaction is not allowed
keyboard_interact_get_responses(true, undefined, _,IoCb, Name, Instr, PromptInfos, Opts, _) ->
keyboard_interact(IoCb, Name, Instr, PromptInfos, Opts);
-keyboard_interact_get_responses(true, Fun, _, Name, Instr, PromptInfos, _, _, NumPrompts) ->
+keyboard_interact_get_responses(true, Fun, _Pwd, _IoCb, Name, Instr, PromptInfos, _Opts, NumPrompts) ->
keyboard_interact_fun(Fun, Name, Instr, PromptInfos, NumPrompts).
keyboard_interact(IoCb, Name, Instr, Prompts, Opts) ->
- if Name /= "" -> IoCb:format("~s", [Name]);
+ if Name /= "" -> IoCb:format("~s~n", [Name]);
true -> ok
end,
- if Instr /= "" -> IoCb:format("~s", [Instr]);
+ if Instr /= "" -> IoCb:format("~s~n", [Instr]);
true -> ok
end,
lists:map(fun({Prompt, true}) -> IoCb:read_line(Prompt, Opts);
@@ -498,33 +512,18 @@ keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
language = "en"}})
end.
-other_alg('ssh-rsa') ->
- 'ssh-dss';
-other_alg('ssh-dss') ->
- 'ssh-rsa'.
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), BinE:Len1/binary,
- ?UINT32(Len2), BinN:Len2/binary>>
- ,"ssh-rsa") ->
- E = ssh_bits:erlint(Len1, BinE),
- N = ssh_bits:erlint(Len2, BinN),
- {ok, #'RSAPublicKey'{publicExponent = E, modulus = N}};
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), BinP:Len1/binary,
- ?UINT32(Len2), BinQ:Len2/binary,
- ?UINT32(Len3), BinG:Len3/binary,
- ?UINT32(Len4), BinY:Len4/binary>>
- , "ssh-dss") ->
- P = ssh_bits:erlint(Len1, BinP),
- Q = ssh_bits:erlint(Len2, BinQ),
- G = ssh_bits:erlint(Len3, BinG),
- Y = ssh_bits:erlint(Len4, BinY),
- {ok, {Y, #'Dss-Parms'{p = P, q = Q, g = G}}};
-
-decode_public_key_v2(_, _) ->
- {error, bad_format}.
-
-encode_public_key(#'RSAPrivateKey'{publicExponent = E, modulus = N}) ->
- ssh_bits:encode(["ssh-rsa",E,N], [string,mpint,mpint]);
-encode_public_key(#'DSAPrivateKey'{p = P, q = Q, g = G, y = Y}) ->
- ssh_bits:encode(["ssh-dss",P,Q,G,Y], [string,mpint,mpint,mpint,mpint]).
+decode_public_key_v2(Bin, _Type) ->
+ try
+ public_key:ssh_decode(Bin, ssh2_pubkey)
+ of
+ Key -> {ok, Key}
+ catch
+ _:_ -> {error, bad_format}
+ end.
+
+encode_public_key(_Alg, Key) ->
+ try
+ public_key:ssh_encode(Key, ssh2_pubkey)
+ catch
+ _:_ -> not_ok
+ end.
diff --git a/lib/ssh/src/ssh_auth.hrl b/lib/ssh/src/ssh_auth.hrl
index 6cd8e6bf14..449bc4fa45 100644
--- a/lib/ssh/src/ssh_auth.hrl
+++ b/lib/ssh/src/ssh_auth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -21,9 +22,6 @@
%%% Description: Ssh User Authentication Protocol
--define(SUPPORTED_AUTH_METHODS, "publickey,keyboard-interactive,password").
-
--define(PREFERRED_PK_ALG, 'ssh-rsa').
-define(SSH_MSG_USERAUTH_REQUEST, 50).
-define(SSH_MSG_USERAUTH_FAILURE, 51).
diff --git a/lib/ssh/src/ssh_bits.erl b/lib/ssh/src/ssh_bits.erl
index 8aaff93b9f..4da3a6018b 100644
--- a/lib/ssh/src/ssh_bits.erl
+++ b/lib/ssh/src/ssh_bits.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -26,7 +27,7 @@
-include("ssh.hrl").
-export([encode/2]).
--export([mpint/1, erlint/2, string/1, name_list/1]).
+-export([mpint/1, string/1, name_list/1]).
-export([random/1]).
-define(name_list(X),
@@ -145,11 +146,7 @@ enc(Xs, ['...'| []], _Offset) ->
enc([], [],_) ->
[].
-erlint(Len, BinInt) ->
- Sz = Len*8,
- <<Int:Sz/big-signed-integer>> = BinInt,
- Int.
-
+
%%
%% Create a binary with constant bytes
%%
diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl
index 5c24f362b1..d15a2c8eba 100644
--- a/lib/ssh/src/ssh_channel.erl
+++ b/lib/ssh/src/ssh_channel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_channel_sup.erl b/lib/ssh/src/ssh_channel_sup.erl
index ee37ed35f8..7c381553b8 100644
--- a/lib/ssh/src/ssh_channel_sup.erl
+++ b/lib/ssh/src/ssh_channel_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 18841e3d2d..71f62a960e 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -98,7 +99,7 @@ handle_ssh_msg({ssh_cm, ConnectionHandler,
Pty = Pty0#ssh_pty{width = Width, height = Height,
pixel_width = PixWidth,
pixel_height = PixHeight},
- {Chars, NewBuf} = io_request({window_change, Pty0}, Buf, Pty),
+ {Chars, NewBuf} = io_request({window_change, Pty0}, Buf, Pty, undefined),
write_chars(ConnectionHandler, ChannelId, Chars),
{ok, State#state{pty = Pty, buf = NewBuf}};
@@ -188,7 +189,7 @@ handle_msg({Group, tty_geometry}, #state{group = Group,
handle_msg({Group, Req}, #state{group = Group, buf = Buf, pty = Pty,
cm = ConnectionHandler,
channel = ChannelId} = State) ->
- {Chars, NewBuf} = io_request(Req, Buf, Pty),
+ {Chars, NewBuf} = io_request(Req, Buf, Pty, Group),
write_chars(ConnectionHandler, ChannelId, Chars),
{ok, State#state{buf = NewBuf}};
@@ -263,40 +264,49 @@ eval(Error) ->
%%% displaying device...
%%% We are *not* really unicode aware yet, we just filter away characters
%%% beyond the latin1 range. We however handle the unicode binaries...
-io_request({window_change, OldTty}, Buf, Tty) ->
+io_request({window_change, OldTty}, Buf, Tty, _Group) ->
window_change(Tty, OldTty, Buf);
-io_request({put_chars, Cs}, Buf, Tty) ->
+io_request({put_chars, Cs}, Buf, Tty, _Group) ->
put_chars(bin_to_list(Cs), Buf, Tty);
-io_request({put_chars, unicode, Cs}, Buf, Tty) ->
+io_request({put_chars, unicode, Cs}, Buf, Tty, _Group) ->
put_chars(unicode:characters_to_list(Cs,unicode), Buf, Tty);
-io_request({insert_chars, Cs}, Buf, Tty) ->
+io_request({insert_chars, Cs}, Buf, Tty, _Group) ->
insert_chars(bin_to_list(Cs), Buf, Tty);
-io_request({insert_chars, unicode, Cs}, Buf, Tty) ->
+io_request({insert_chars, unicode, Cs}, Buf, Tty, _Group) ->
insert_chars(unicode:characters_to_list(Cs,unicode), Buf, Tty);
-io_request({move_rel, N}, Buf, Tty) ->
+io_request({move_rel, N}, Buf, Tty, _Group) ->
move_rel(N, Buf, Tty);
-io_request({delete_chars,N}, Buf, Tty) ->
+io_request({delete_chars,N}, Buf, Tty, _Group) ->
delete_chars(N, Buf, Tty);
-io_request(beep, Buf, _Tty) ->
+io_request(beep, Buf, _Tty, _Group) ->
{[7], Buf};
%% New in R12
-io_request({get_geometry,columns},Buf,Tty) ->
+io_request({get_geometry,columns},Buf,Tty, _Group) ->
{ok, Tty#ssh_pty.width, Buf};
-io_request({get_geometry,rows},Buf,Tty) ->
+io_request({get_geometry,rows},Buf,Tty, _Group) ->
{ok, Tty#ssh_pty.height, Buf};
-io_request({requests,Rs}, Buf, Tty) ->
- io_requests(Rs, Buf, Tty, []);
-io_request(tty_geometry, Buf, Tty) ->
- io_requests([{move_rel, 0}, {put_chars, unicode, [10]}], Buf, Tty, []);
+io_request({requests,Rs}, Buf, Tty, Group) ->
+ io_requests(Rs, Buf, Tty, [], Group);
+io_request(tty_geometry, Buf, Tty, Group) ->
+ io_requests([{move_rel, 0}, {put_chars, unicode, [10]}],
+ Buf, Tty, [], Group);
%{[], Buf};
-io_request(_R, Buf, _Tty) ->
+
+%% New in 18
+io_request({put_chars_sync, Class, Cs, Reply}, Buf, Tty, Group) ->
+ %% We handle these asynchronous for now, if we need output guarantees
+ %% we have to handle these synchronously
+ Group ! {reply, Reply},
+ io_request({put_chars, Class, Cs}, Buf, Tty, Group);
+
+io_request(_R, Buf, _Tty, _Group) ->
{[], Buf}.
-io_requests([R|Rs], Buf, Tty, Acc) ->
- {Chars, NewBuf} = io_request(R, Buf, Tty),
- io_requests(Rs, NewBuf, Tty, [Acc|Chars]);
-io_requests([], Buf, _Tty, Acc) ->
+io_requests([R|Rs], Buf, Tty, Acc, Group) ->
+ {Chars, NewBuf} = io_request(R, Buf, Tty, Group),
+ io_requests(Rs, NewBuf, Tty, [Acc|Chars], Group);
+io_requests([], Buf, _Tty, Acc, _Group) ->
{Acc, Buf}.
%%% return commands for cursor navigation, assume everything is ansi
diff --git a/lib/ssh/src/ssh_client_key.erl b/lib/ssh/src/ssh_client_key.erl
index 2c48884dc2..0758865ad1 100644
--- a/lib/ssh/src/ssh_client_key.erl
+++ b/lib/ssh/src/ssh_client_key.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index a17c7cbc77..7fe97b6c13 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index d14f7ce27d..9f9f3de8fa 100644
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -247,6 +248,9 @@
local_id, %% local channel id
recv_window_size,
+ recv_window_pending = 0, %% Sum of window size updates that has not
+ %% yet been sent. This limits the number
+ %% of sent update msgs.
recv_packet_size,
recv_close = false,
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 654b9d4bde..a34478732c 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -196,15 +197,16 @@ reply_request(_,false, _, _) ->
%%--------------------------------------------------------------------
ptty_alloc(ConnectionHandler, Channel, Options) ->
ptty_alloc(ConnectionHandler, Channel, Options, infinity).
-ptty_alloc(ConnectionHandler, Channel, Options, TimeOut) ->
+ptty_alloc(ConnectionHandler, Channel, Options0, TimeOut) ->
+ Options = backwards_compatible(Options0, []),
{Width, PixWidth} = pty_default_dimensions(width, Options),
- {Hight, PixHight} = pty_default_dimensions(hight, Options),
+ {Height, PixHeight} = pty_default_dimensions(height, Options),
pty_req(ConnectionHandler, Channel,
- proplists:get_value(term, Options, default_term()),
+ proplists:get_value(term, Options, os:getenv("TERM", ?DEFAULT_TERMINAL)),
proplists:get_value(width, Options, Width),
- proplists:get_value(hight, Options, Hight),
+ proplists:get_value(height, Options, Height),
proplists:get_value(pixel_widh, Options, PixWidth),
- proplists:get_value(pixel_hight, Options, PixHight),
+ proplists:get_value(pixel_height, Options, PixHeight),
proplists:get_value(pty_opts, Options, []), TimeOut
).
%%--------------------------------------------------------------------
@@ -660,7 +662,7 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)},
try
- {ok, Pid} = start_subsytem(SsName, Connection, Channel0, ReplyMsg),
+ {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg),
erlang:monitor(process, Pid),
Channel = Channel0#channel{user = Pid},
ssh_channel:cache_update(Cache, Channel),
@@ -933,14 +935,27 @@ encode_ip(Addr) when is_list(Addr) ->
end
end.
-start_channel(Cb, Id, Args, SubSysSup) ->
- start_channel(Cb, Id, Args, SubSysSup, undefined).
+start_channel(Cb, Id, Args, SubSysSup, Opts) ->
+ start_channel(Cb, Id, Args, SubSysSup, undefined, Opts).
-start_channel(Cb, Id, Args, SubSysSup, Exec) ->
+start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) ->
ChildSpec = child_spec(Cb, Id, Args, Exec),
ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup),
+ assert_limit_num_channels_not_exceeded(ChannelSup, Opts),
ssh_channel_sup:start_child(ChannelSup, ChildSpec).
+assert_limit_num_channels_not_exceeded(ChannelSup, Opts) ->
+ MaxNumChannels = proplists:get_value(max_channels, Opts, infinity),
+ NumChannels = length([x || {_,_,worker,[ssh_channel]} <-
+ supervisor:which_children(ChannelSup)]),
+ if
+ %% Note that NumChannels is BEFORE starting a new one
+ NumChannels < MaxNumChannels ->
+ ok;
+ true ->
+ throw(max_num_channels_exceeded)
+ end.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -996,17 +1011,19 @@ child_spec(Callback, Id, Args, Exec) ->
start_cli(#connection{cli_spec = no_cli}, _) ->
{error, cli_disabled};
-start_cli(#connection{cli_spec = {CbModule, Args}, exec = Exec,
+start_cli(#connection{options = Options,
+ cli_spec = {CbModule, Args},
+ exec = Exec,
sub_system_supervisor = SubSysSup}, ChannelId) ->
- start_channel(CbModule, ChannelId, Args, SubSysSup, Exec).
+ start_channel(CbModule, ChannelId, Args, SubSysSup, Exec, Options).
-start_subsytem(BinName, #connection{options = Options,
+start_subsystem(BinName, #connection{options = Options,
sub_system_supervisor = SubSysSup},
#channel{local_id = ChannelId}, _ReplyMsg) ->
Name = binary_to_list(BinName),
case check_subsystem(Name, Options) of
{Callback, Opts} when is_atom(Callback), Callback =/= none ->
- start_channel(Callback, ChannelId, Opts, SubSysSup);
+ start_channel(Callback, ChannelId, Opts, SubSysSup, Options);
{Other, _} when Other =/= none ->
{error, legacy_option_not_supported}
end.
@@ -1340,10 +1357,11 @@ decode_ip(Addr) when is_binary(Addr) ->
{ok,A} -> A
end.
-default_term() ->
- case os:getenv("TERM") of
- false ->
- ?DEFAULT_TERMINAL;
- Str when is_list(Str)->
- Str
- end.
+backwards_compatible([], Acc) ->
+ Acc;
+backwards_compatible([{hight, Value} | Rest], Acc) ->
+ backwards_compatible(Rest, [{height, Value} | Acc]);
+backwards_compatible([{pixel_hight, Value} | Rest], Acc) ->
+ backwards_compatible(Rest, [{height, Value} | Acc]);
+backwards_compatible([Value| Rest], Acc) ->
+ backwards_compatible(Rest, [ Value | Acc]).
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index f751094211..ce1931e4f4 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -33,7 +34,7 @@
-include("ssh_transport.hrl").
-include("ssh_auth.hrl").
-include("ssh_connect.hrl").
-
+-compile(export_all).
-export([start_link/3]).
%% Internal application API
@@ -45,8 +46,13 @@
get_print_info/1]).
%% gen_fsm callbacks
--export([hello/2, kexinit/2, key_exchange/2, new_keys/2,
- userauth/2, connected/2,
+-export([hello/2, kexinit/2, key_exchange/2,
+ key_exchange_dh_gex_init/2, key_exchange_dh_gex_reply/2,
+ new_keys/2,
+ service_request/2, connected/2,
+ userauth/2,
+ userauth_keyboard_interactive/2,
+ userauth_keyboard_interactive_info_response/2,
error/2]).
-export([init/1, handle_event/3,
@@ -70,6 +76,8 @@
undecoded_packet_length, % integer()
key_exchange_init_msg, % #ssh_msg_kexinit{}
renegotiate = false, % boolean()
+ last_size_rekey = 0,
+ event_queue = [],
connection_queue,
address,
port,
@@ -77,11 +85,21 @@
recbuf
}).
--type state_name() :: hello | kexinit | key_exchange | new_keys | userauth | connection.
+-type state_name() :: hello | kexinit | key_exchange | key_exchange_dh_gex_init |
+ key_exchange_dh_gex_reply | new_keys | service_request |
+ userauth | userauth_keyboard_interactive |
+ userauth_keyboard_interactive_info_response |
+ connection.
+
-type gen_fsm_state_return() :: {next_state, state_name(), term()} |
{next_state, state_name(), term(), timeout()} |
{stop, term(), term()}.
+-type gen_fsm_sync_return() :: {next_state, state_name(), term()} |
+ {next_state, state_name(), term(), timeout()} |
+ {reply, term(), state_name(), term()} |
+ {stop, term(), term(), term()}.
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -409,59 +427,91 @@ key_exchange(#ssh_msg_kexdh_reply{} = Msg,
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
+key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
+key_exchange(#ssh_msg_kex_dh_gex_request_old{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
key_exchange(#ssh_msg_kex_dh_gex_group{} = Msg,
+ #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
+ {ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
+ send_msg(KexGexInit, State),
+ {next_state, key_exchange_dh_gex_reply, next_packet(State#state{ssh_params = Ssh})};
+
+key_exchange(#ssh_msg_kex_ecdh_init{} = Msg,
#state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
- {ok, NextKexMsg, Ssh1} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
- send_msg(NextKexMsg, State),
+ {ok, KexEcdhReply, Ssh1} = ssh_transport:handle_kex_ecdh_init(Msg, Ssh0),
+ send_msg(KexEcdhReply, State),
{ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
-key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
+key_exchange(#ssh_msg_kex_ecdh_reply{} = Msg,
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
- {ok, NextKexMsg, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
- send_msg(NextKexMsg, State),
- {next_state, new_keys, next_packet(State#state{ssh_params = Ssh})};
+ {ok, NewKeys, Ssh} = ssh_transport:handle_kex_ecdh_reply(Msg, Ssh0),
+ send_msg(NewKeys, State),
+ {next_state, new_keys, next_packet(State#state{ssh_params = Ssh})}.
-key_exchange(#ssh_msg_kex_dh_gex_reply{} = Msg,
- #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
- {ok, NewKeys, Ssh} = ssh_transport:handle_kex_dh_gex_reply(Msg, Ssh0),
+%%--------------------------------------------------------------------
+-spec key_exchange_dh_gex_init(#ssh_msg_kex_dh_gex_init{}, #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
+key_exchange_dh_gex_init(#ssh_msg_kex_dh_gex_init{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, KexGexReply, Ssh1} = ssh_transport:handle_kex_dh_gex_init(Msg, Ssh0),
+ send_msg(KexGexReply, State),
+ {ok, NewKeys, Ssh} = ssh_transport:new_keys_message(Ssh1),
send_msg(NewKeys, State),
{next_state, new_keys, next_packet(State#state{ssh_params = Ssh})}.
%%--------------------------------------------------------------------
+-spec key_exchange_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{}, #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
+key_exchange_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{} = Msg,
+ #state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
+ {ok, NewKeys, Ssh1} = ssh_transport:handle_kex_dh_gex_reply(Msg, Ssh0),
+ send_msg(NewKeys, State),
+ {next_state, new_keys, next_packet(State#state{ssh_params = Ssh1})}.
+
+%%--------------------------------------------------------------------
-spec new_keys(#ssh_msg_newkeys{}, #state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
new_keys(#ssh_msg_newkeys{} = Msg, #state{ssh_params = Ssh0} = State0) ->
{ok, Ssh} = ssh_transport:handle_new_keys(Msg, Ssh0),
- {NextStateName, State} =
- after_new_keys(State0#state{ssh_params = Ssh}),
- {next_state, NextStateName, next_packet(State)}.
+ after_new_keys(next_packet(State0#state{ssh_params = Ssh})).
%%--------------------------------------------------------------------
--spec userauth(#ssh_msg_service_request{} | #ssh_msg_service_accept{} |
- #ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
- #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
- #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
- #state{}) -> gen_fsm_state_return().
+-spec service_request(#ssh_msg_service_request{} | #ssh_msg_service_accept{},
+ #state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
-
-userauth(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
+service_request(#ssh_msg_service_request{name = "ssh-userauth"} = Msg,
#state{ssh_params = #ssh{role = server,
session_id = SessionId} = Ssh0} = State) ->
{ok, {Reply, Ssh}} = ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0),
send_msg(Reply, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-userauth(#ssh_msg_service_accept{name = "ssh-userauth"},
- #state{ssh_params = #ssh{role = client,
- service = "ssh-userauth"} = Ssh0} =
- State) ->
+service_request(#ssh_msg_service_accept{name = "ssh-userauth"},
+ #state{ssh_params = #ssh{role = client,
+ service = "ssh-userauth"} = Ssh0} =
+ State) ->
{Msg, Ssh} = ssh_auth:init_userauth_request_msg(Ssh0),
send_msg(Msg, State),
- {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})};
+ {next_state, userauth, next_packet(State#state{auth_user = Ssh#ssh.user, ssh_params = Ssh})}.
+%%--------------------------------------------------------------------
+-spec userauth(#ssh_msg_userauth_request{} | #ssh_msg_userauth_info_request{} |
+ #ssh_msg_userauth_info_response{} | #ssh_msg_userauth_success{} |
+ #ssh_msg_userauth_failure{} | #ssh_msg_userauth_banner{},
+ #state{}) -> gen_fsm_state_return().
+%%--------------------------------------------------------------------
userauth(#ssh_msg_userauth_request{service = "ssh-connection",
method = "none"} = Msg,
#state{ssh_params = #ssh{session_id = SessionId, role = server,
@@ -478,43 +528,28 @@ userauth(#ssh_msg_userauth_request{service = "ssh-connection",
service = "ssh-connection",
peer = {_, Address}} = Ssh0,
opts = Opts, starter = Pid} = State) ->
- case ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_msg(Reply, State),
- Pid ! ssh_connected,
- connected_fun(User, Address, Method, Opts),
- {next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
- {not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Address, Reason, Opts),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ case lists:member(Method, Ssh0#ssh.userauth_methods) of
+ true ->
+ case ssh_auth:handle_userauth_request(Msg, SessionId, Ssh0) of
+ {authorized, User, {Reply, Ssh}} ->
+ send_msg(Reply, State),
+ Pid ! ssh_connected,
+ connected_fun(User, Address, Method, Opts),
+ {next_state, connected,
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} when Method == "keyboard-interactive" ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
+ false ->
+ userauth(Msg#ssh_msg_userauth_request{method="none"}, State)
end;
-userauth(#ssh_msg_userauth_info_request{} = Msg,
- #state{ssh_params = #ssh{role = client,
- io_cb = IoCb} = Ssh0} = State) ->
- {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})};
-
-userauth(#ssh_msg_userauth_info_response{} = Msg,
- #state{ssh_params = #ssh{role = server,
- peer = {_, Address}} = Ssh0,
- opts = Opts, starter = Pid} = State) ->
- case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
- {authorized, User, {Reply, Ssh}} ->
- send_msg(Reply, State),
- Pid ! ssh_connected,
- connected_fun(User, Address, "keyboard-interactive", Opts),
- {next_state, connected,
- next_packet(State#state{auth_user = User, ssh_params = Ssh})};
- {not_authorized, {User, Reason}, {Reply, Ssh}} ->
- retry_fun(User, Address, Reason, Opts),
- send_msg(Reply, State),
- {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
- end;
-
userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client} = Ssh,
starter = Pid} = State) ->
Pid ! ssh_connected,
@@ -541,19 +576,25 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
{disconnect, DisconnectMsg, {Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
%% The prefered authentication method failed try next method
-userauth(#ssh_msg_userauth_failure{},
+userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
case ssh_auth:userauth_request_msg(Ssh0) of
{disconnect, DisconnectMsg,{Msg, Ssh}} ->
send_msg(Msg, State),
handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
- {Msg, Ssh} ->
+ {"keyboard-interactive", {Msg, Ssh}} ->
+ send_msg(Msg, State),
+ {next_state, userauth_keyboard_interactive, next_packet(State#state{ssh_params = Ssh})};
+ {_Method, {Msg, Ssh}} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
@@ -568,15 +609,63 @@ userauth(#ssh_msg_userauth_banner{message = Msg},
io:format("~s", [Msg]),
{next_state, userauth, next_packet(State)}.
+
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_request{} = Msg,
+ #state{ssh_params = #ssh{role = client,
+ io_cb = IoCb} = Ssh0} = State) ->
+ {ok, {Reply, Ssh}} = ssh_auth:handle_userauth_info_request(Msg, IoCb, Ssh0),
+ send_msg(Reply, State),
+ {next_state, userauth_keyboard_interactive_info_response, next_packet(State#state{ssh_params = Ssh})};
+
+userauth_keyboard_interactive(#ssh_msg_userauth_info_response{} = Msg,
+ #state{ssh_params = #ssh{role = server,
+ peer = {_, Address}} = Ssh0,
+ opts = Opts, starter = Pid} = State) ->
+ case ssh_auth:handle_userauth_info_response(Msg, Ssh0) of
+ {authorized, User, {Reply, Ssh}} ->
+ send_msg(Reply, State),
+ Pid ! ssh_connected,
+ connected_fun(User, Address, "keyboard-interactive", Opts),
+ {next_state, connected,
+ next_packet(State#state{auth_user = User, ssh_params = Ssh#ssh{authenticated = true}})};
+ {not_authorized, {User, Reason}, {Reply, Ssh}} ->
+ retry_fun(User, Address, Reason, Opts),
+ send_msg(Reply, State),
+ {next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
+ end;
+userauth_keyboard_interactive(Msg = #ssh_msg_userauth_failure{},
+ #state{ssh_params = Ssh0 =
+ #ssh{role = client,
+ userauth_preference = Prefs0}}
+ = State) ->
+ Prefs = [{Method,M,F,A} || {Method,M,F,A} <- Prefs0,
+ Method =/= "keyboard-interactive"],
+ userauth(Msg, State#state{ssh_params = Ssh0#ssh{userauth_preference=Prefs}}).
+
+
+
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_failure{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State);
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_success{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth(Msg, State);
+userauth_keyboard_interactive_info_response(Msg=#ssh_msg_userauth_info_request{},
+ #state{ssh_params = #ssh{role = client}} = State) ->
+ userauth_keyboard_interactive(Msg, State).
+
%%--------------------------------------------------------------------
-spec connected({#ssh_msg_kexinit{}, binary()}, %%| %% #ssh_msg_kexdh_init{},
#state{}) -> gen_fsm_state_return().
%%--------------------------------------------------------------------
-connected({#ssh_msg_kexinit{}, _Payload} = Event, State) ->
- kexinit(Event, State#state{renegotiate = true}).
-%% ;
-%% connected(#ssh_msg_kexdh_init{} = Event, State) ->
-%% key_exchange(Event, State#state{renegotiate = true}).
+connected({#ssh_msg_kexinit{}, _Payload} = Event, #state{ssh_params = Ssh0} = State0) ->
+ {KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh0),
+ State = State0#state{ssh_params = Ssh,
+ key_exchange_init_msg = KeyInitMsg,
+ renegotiate = true},
+ send_msg(SshPacket, State),
+ kexinit(Event, State).
%%--------------------------------------------------------------------
-spec handle_event(#ssh_msg_disconnect{} | #ssh_msg_ignore{} | #ssh_msg_debug{} |
@@ -605,33 +694,6 @@ handle_event(#ssh_msg_debug{always_display = Display, message = DbgMsg, language
handle_event(#ssh_msg_unimplemented{}, StateName, State) ->
{next_state, StateName, next_packet(State)};
-handle_event({adjust_window, ChannelId, Bytes}, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State0) ->
- State =
- case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{recv_window_size = WinSize, remote_id = Id} = Channel ->
- ssh_channel:cache_update(Cache, Channel#channel{recv_window_size =
- WinSize + Bytes}),
- Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes),
- send_replies([{connection_reply, Msg}], State0);
- undefined ->
- State0
- end,
- {next_state, StateName, next_packet(State)};
-
-handle_event({reply_request, success, ChannelId}, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State0) ->
- State = case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{remote_id = RemoteId} ->
- Msg = ssh_connection:channel_success_msg(RemoteId),
- send_replies([{connection_reply, Msg}], State0);
- undefined ->
- State0
- end,
- {next_state, StateName, State};
-
handle_event(renegotiate, connected, #state{ssh_params = Ssh0}
= State) ->
{KeyInitMsg, SshPacket, Ssh} = ssh_transport:key_exchange_init_msg(Ssh0),
@@ -643,13 +705,13 @@ handle_event(renegotiate, connected, #state{ssh_params = Ssh0}
renegotiate = true})};
handle_event(renegotiate, StateName, State) ->
- timer:apply_after(?REKEY_TIMOUT, gen_fsm, send_all_state_event, [self(), renegotiate]),
- %% Allready in keyexcahange so ignore
+ %% Already in key-exchange so safe to ignore
{next_state, StateName, State};
%% Rekey due to sent data limit reached?
handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
- {ok, [{send_oct,Sent}]} = inet:getstat(State#state.socket, [send_oct]),
+ {ok, [{send_oct,Sent0}]} = inet:getstat(State#state.socket, [send_oct]),
+ Sent = Sent0 - State#state.last_size_rekey,
MaxSent = proplists:get_value(rekey_limit, State#state.opts, 1024000000),
timer:apply_after(?REKEY_DATA_TIMOUT, gen_fsm, send_all_state_event, [self(), data_size]),
case Sent >= MaxSent of
@@ -659,11 +721,59 @@ handle_event(data_size, connected, #state{ssh_params = Ssh0} = State) ->
{next_state, kexinit,
next_packet(State#state{ssh_params = Ssh,
key_exchange_init_msg = KeyInitMsg,
- renegotiate = true})};
+ renegotiate = true,
+ last_size_rekey = Sent0})};
_ ->
{next_state, connected, next_packet(State)}
end;
handle_event(data_size, StateName, State) ->
+ %% Already in key-exchange so safe to ignore
+ {next_state, StateName, State};
+
+handle_event(Event, StateName, State) when StateName /= connected ->
+ Events = [{event, Event} | State#state.event_queue],
+ {next_state, StateName, State#state{event_queue = Events}};
+
+handle_event({adjust_window, ChannelId, Bytes}, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State0) ->
+ State =
+ case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ recv_packet_size = PktSize} = Channel
+ when (WinSize-Bytes) >= 2*PktSize ->
+ %% The peer can send at least two more *full* packet, no hurry.
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_pending = Pending + Bytes}),
+ State0;
+
+ #channel{recv_window_size = WinSize,
+ recv_window_pending = Pending,
+ remote_id = Id} = Channel ->
+ %% Now we have to update the window - we can't receive so many more pkts
+ ssh_channel:cache_update(Cache,
+ Channel#channel{recv_window_size =
+ WinSize + Bytes + Pending,
+ recv_window_pending = 0}),
+ Msg = ssh_connection:channel_adjust_window_msg(Id, Bytes + Pending),
+ send_replies([{connection_reply, Msg}], State0);
+
+ undefined ->
+ State0
+ end,
+ {next_state, StateName, next_packet(State)};
+
+handle_event({reply_request, success, ChannelId}, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State0) ->
+ State = case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{remote_id = RemoteId} ->
+ Msg = ssh_connection:channel_success_msg(RemoteId),
+ send_replies([{connection_reply, Msg}], State0);
+ undefined ->
+ State0
+ end,
{next_state, StateName, State};
handle_event({request, ChannelPid, ChannelId, Type, Data}, StateName, State0) ->
@@ -694,8 +804,62 @@ handle_event({unknown, Data}, StateName, State) ->
sockname]} | {channel_info, channel_id(), [recv_window |
send_window]} |
{close, channel_id()} | stop, term(), state_name(), #state{})
- -> gen_fsm_state_return().
+ -> gen_fsm_sync_return().
%%--------------------------------------------------------------------
+handle_sync_event(get_print_info, _From, StateName, State) ->
+ Reply =
+ try
+ {inet:sockname(State#state.socket),
+ inet:peername(State#state.socket)
+ }
+ of
+ {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])};
+ _ -> {{"-",0},"-"}
+ catch
+ _:_ -> {{"?",0},"?"}
+ end,
+ {reply, Reply, StateName, State};
+
+handle_sync_event({connection_info, Options}, _From, StateName, State) ->
+ Info = ssh_info(Options, State, []),
+ {reply, Info, StateName, State};
+
+handle_sync_event({channel_info, ChannelId, Options}, _From, StateName,
+ #state{connection_state = #connection{channel_cache = Cache}} = State) ->
+ case ssh_channel:cache_lookup(Cache, ChannelId) of
+ #channel{} = Channel ->
+ Info = ssh_channel_info(Options, Channel, []),
+ {reply, Info, StateName, State};
+ undefined ->
+ {reply, [], StateName, State}
+ end;
+
+handle_sync_event({info, ChannelPid}, _From, StateName,
+ #state{connection_state =
+ #connection{channel_cache = Cache}} = State) ->
+ Result = ssh_channel:cache_foldl(
+ fun(Channel, Acc) when ChannelPid == all;
+ Channel#channel.user == ChannelPid ->
+ [Channel | Acc];
+ (_, Acc) ->
+ Acc
+ end, [], Cache),
+ {reply, {ok, Result}, StateName, State};
+
+handle_sync_event(stop, _, _StateName, #state{connection_state = Connection0,
+ role = Role} = State0) ->
+ {disconnect, _Reason, {{replies, Replies}, Connection}} =
+ ssh_connection:handle_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "User closed down connection",
+ language = "en"}, Connection0, Role),
+ State = send_replies(Replies, State0),
+ {stop, normal, ok, State#state{connection_state = Connection}};
+
+
+handle_sync_event(Event, From, StateName, State) when StateName /= connected ->
+ Events = [{sync, Event, From} | State#state.event_queue],
+ {next_state, StateName, State#state{event_queue = Events}};
+
handle_sync_event({request, ChannelPid, ChannelId, Type, Data, Timeout}, From, StateName, State0) ->
{{replies, Replies}, State1} = handle_request(ChannelPid,
ChannelId, Type, Data,
@@ -798,46 +962,6 @@ handle_sync_event({recv_window, ChannelId}, _From, StateName,
end,
{reply, Reply, StateName, next_packet(State)};
-handle_sync_event(get_print_info, _From, StateName, State) ->
- Reply =
- try
- {inet:sockname(State#state.socket),
- inet:peername(State#state.socket)
- }
- of
- {{ok,Local}, {ok,Remote}} -> {{Local,Remote},io_lib:format("statename=~p",[StateName])};
- _ -> {{"-",0},"-"}
- catch
- _:_ -> {{"?",0},"?"}
- end,
- {reply, Reply, StateName, State};
-
-handle_sync_event({connection_info, Options}, _From, StateName, State) ->
- Info = ssh_info(Options, State, []),
- {reply, Info, StateName, State};
-
-handle_sync_event({channel_info, ChannelId, Options}, _From, StateName,
- #state{connection_state = #connection{channel_cache = Cache}} = State) ->
- case ssh_channel:cache_lookup(Cache, ChannelId) of
- #channel{} = Channel ->
- Info = ssh_channel_info(Options, Channel, []),
- {reply, Info, StateName, State};
- undefined ->
- {reply, [], StateName, State}
- end;
-
-handle_sync_event({info, ChannelPid}, _From, StateName,
- #state{connection_state =
- #connection{channel_cache = Cache}} = State) ->
- Result = ssh_channel:cache_foldl(
- fun(Channel, Acc) when ChannelPid == all;
- Channel#channel.user == ChannelPid ->
- [Channel | Acc];
- (_, Acc) ->
- Acc
- end, [], Cache),
- {reply, {ok, Result}, StateName, State};
-
handle_sync_event({close, ChannelId}, _, StateName,
#state{connection_state =
#connection{channel_cache = Cache}} = State0) ->
@@ -852,19 +976,7 @@ handle_sync_event({close, ChannelId}, _, StateName,
undefined ->
State0
end,
- {reply, ok, StateName, next_packet(State)};
-
-handle_sync_event(stop, _, _StateName, #state{connection_state = Connection0,
- role = Role,
- opts = Opts} = State0) ->
- {disconnect, Reason, {{replies, Replies}, Connection}} =
- ssh_connection:handle_msg(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "User closed down connection",
- language = "en"}, Connection0, Role),
- State = send_replies(Replies, State0),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, normal, ok, State#state{connection_state = Connection}}.
+ {reply, ok, StateName, next_packet(State)}.
%%--------------------------------------------------------------------
-spec handle_info({atom(), port(), binary()} | {atom(), port()} |
@@ -881,57 +993,55 @@ handle_info({Protocol, Socket, Info}, hello,
transport_protocol = Protocol} = State) ->
event({info_line, Info}, hello, State);
-handle_info({Protocol, Socket, Data}, Statename,
+handle_info({Protocol, Socket, Data}, StateName,
#state{socket = Socket,
transport_protocol = Protocol,
- ssh_params = #ssh{decrypt_block_size = BlockSize,
- recv_mac_size = MacSize} = Ssh0,
- decoded_data_buffer = <<>>,
- encoded_data_buffer = EncData0} = State0) ->
-
- %% Implementations SHOULD decrypt the length after receiving the
- %% first 8 (or cipher block size, whichever is larger) bytes of a
- %% packet. (RFC 4253: Section 6 - Binary Packet Protocol)
- case size(EncData0) + size(Data) >= erlang:max(8, BlockSize) of
- true ->
- {Ssh, SshPacketLen, DecData, EncData} =
-
- ssh_transport:decrypt_first_block(<<EncData0/binary,
- Data/binary>>, Ssh0),
- case SshPacketLen > ?SSH_MAX_PACKET_SIZE of
- true ->
- DisconnectMsg =
- #ssh_msg_disconnect{code =
- ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad packet length "
- ++ integer_to_list(SshPacketLen),
- language = "en"},
- handle_disconnect(DisconnectMsg, State0);
- false ->
- RemainingSshPacketLen =
- (SshPacketLen + ?SSH_LENGHT_INDICATOR_SIZE) -
- BlockSize + MacSize,
- State = State0#state{ssh_params = Ssh},
- handle_ssh_packet_data(RemainingSshPacketLen,
- DecData, EncData, Statename,
- State)
- end;
- false ->
- {next_state, Statename,
- next_packet(State0#state{encoded_data_buffer =
- <<EncData0/binary, Data/binary>>})}
- end;
-
-handle_info({Protocol, Socket, Data}, Statename,
- #state{socket = Socket,
- transport_protocol = Protocol,
- decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length = Len} =
- State) when is_integer(Len) ->
- handle_ssh_packet_data(Len, DecData, <<EncData/binary, Data/binary>>,
- Statename, State);
+ ssh_params = Ssh0,
+ decoded_data_buffer = DecData0,
+ encoded_data_buffer = EncData0,
+ undecoded_packet_length = RemainingSshPacketLen0} = State0) ->
+ Encoded = <<EncData0/binary, Data/binary>>,
+ try ssh_transport:handle_packet_part(DecData0, Encoded, RemainingSshPacketLen0, Ssh0)
+ of
+ {get_more, DecBytes, EncDataRest, RemainingSshPacketLen, Ssh1} ->
+ {next_state, StateName,
+ next_packet(State0#state{encoded_data_buffer = EncDataRest,
+ decoded_data_buffer = DecBytes,
+ undecoded_packet_length = RemainingSshPacketLen,
+ ssh_params = Ssh1})};
+ {decoded, MsgBytes, EncDataRest, Ssh1} ->
+ generate_event(MsgBytes, StateName,
+ State0#state{ssh_params = Ssh1,
+ %% Important to be set for
+ %% next_packet
+%%% FIXME: the following three seem to always be set in generate_event!
+ decoded_data_buffer = <<>>,
+ undecoded_packet_length = undefined,
+ encoded_data_buffer = EncDataRest},
+ EncDataRest);
+ {bad_mac, Ssh1} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad mac",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0#state{ssh_params=Ssh1});
+ {error, {exceeds_max_size,PacketLen}} ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet length "
+ ++ integer_to_list(PacketLen),
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
+ catch
+ _:_ ->
+ DisconnectMsg =
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet",
+ language = ""},
+ handle_disconnect(DisconnectMsg, State0)
+ end;
+
handle_info({CloseTag, _Socket}, _StateName,
#state{transport_close_tag = CloseTag,
ssh_params = #ssh{role = _Role, opts = _Opts}} = State) ->
@@ -969,15 +1079,38 @@ handle_info({check_cache, _ , _},
#connection{channel_cache = Cache}} = State) ->
{next_state, StateName, check_cache(State, Cache)};
-handle_info(UnexpectedMessage, StateName, #state{ssh_params = SshParams} = State) ->
- Msg = lists:flatten(io_lib:format(
- "Unexpected message '~p' received in state '~p'\n"
- "Role: ~p\n"
- "Peer: ~p\n"
- "Local Address: ~p\n", [UnexpectedMessage, StateName,
- SshParams#ssh.role, SshParams#ssh.peer,
- proplists:get_value(address, SshParams#ssh.opts)])),
- error_logger:info_report(Msg),
+handle_info(UnexpectedMessage, StateName, #state{opts = Opts,
+ ssh_params = SshParams} = State) ->
+ case unexpected_fun(UnexpectedMessage, Opts, SshParams) of
+ report ->
+ Msg = lists:flatten(
+ io_lib:format(
+ "Unexpected message '~p' received in state '~p'\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [UnexpectedMessage, StateName,
+ SshParams#ssh.role, SshParams#ssh.peer,
+ proplists:get_value(address, SshParams#ssh.opts)])),
+ error_logger:info_report(Msg);
+
+ skip ->
+ ok;
+
+ Other ->
+ Msg = lists:flatten(
+ io_lib:format("Call to fun in 'unexpectedfun' failed:~n"
+ "Return: ~p\n"
+ "Message: ~p\n"
+ "Role: ~p\n"
+ "Peer: ~p\n"
+ "Local Address: ~p\n", [Other, UnexpectedMessage,
+ SshParams#ssh.role,
+ element(2,SshParams#ssh.peer),
+ proplists:get_value(address, SshParams#ssh.opts)]
+ )),
+
+ error_logger:error_report(Msg)
+ end,
{next_state, StateName, State}.
%%--------------------------------------------------------------------
@@ -986,7 +1119,7 @@ handle_info(UnexpectedMessage, StateName, #state{ssh_params = SshParams} = State
terminate(normal, _, #state{transport_cb = Transport,
connection_state = Connection,
socket = Socket}) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
(catch Transport:close(Socket)),
ok;
@@ -1015,7 +1148,7 @@ terminate({shutdown, _}, StateName, State) ->
terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
connection_state = Connection} = State) ->
- terminate_subsytem(Connection),
+ terminate_subsystem(Connection),
log_error(Reason),
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
@@ -1026,10 +1159,10 @@ terminate(Reason, StateName, #state{ssh_params = Ssh0, starter = _Pid,
terminate(normal, StateName, State#state{ssh_params = Ssh}).
-terminate_subsytem(#connection{system_supervisor = SysSup,
+terminate_subsystem(#connection{system_supervisor = SysSup,
sub_system_supervisor = SubSysSup}) when is_pid(SubSysSup) ->
ssh_system_sup:stop_subsystem(SysSup, SubSysSup);
-terminate_subsytem(_) ->
+terminate_subsystem(_) ->
ok.
format_status(normal, [_, State]) ->
@@ -1129,13 +1262,16 @@ init_ssh(client = Role, Vsn, Version, Options, Socket) ->
opts = Options,
userauth_supported_methods = AuthMethods,
peer = {PeerName, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
};
init_ssh(server = Role, Vsn, Version, Options, Socket) ->
-
AuthMethods = proplists:get_value(auth_methods, Options,
?SUPPORTED_AUTH_METHODS),
+ AuthMethodsAsList = string:tokens(AuthMethods, ","),
{ok, PeerAddr} = inet:peername(Socket),
KeyCb = proplists:get_value(key_cb, Options, ssh_file),
@@ -1146,60 +1282,45 @@ init_ssh(server = Role, Vsn, Version, Options, Socket) ->
io_cb = proplists:get_value(io_cb, Options, ssh_io),
opts = Options,
userauth_supported_methods = AuthMethods,
+ userauth_methods = AuthMethodsAsList,
+ kb_tries_left = 3,
peer = {undefined, PeerAddr},
- available_host_keys = supported_host_keys(Role, KeyCb, Options)
+ available_host_keys = supported_host_keys(Role, KeyCb, Options),
+ random_length_padding = proplists:get_value(max_random_length_padding,
+ Options,
+ (#ssh{})#ssh.random_length_padding)
}.
supported_host_keys(client, _, Options) ->
try
- case extract_algs(proplists:get_value(pref_public_key_algs, Options, false), []) of
- false ->
- ["ssh-rsa", "ssh-dss"];
- Algs ->
- Algs
+ case proplists:get_value(public_key,
+ proplists:get_value(preferred_algorithms,Options,[])
+ ) of
+ undefined ->
+ ssh_transport:default_algorithms(public_key);
+ L ->
+ L -- (L--ssh_transport:default_algorithms(public_key))
end
+ of
+ [] ->
+ {stop, {shutdown, "No public key algs"}};
+ Algs ->
+ [atom_to_list(A) || A<-Algs]
catch
exit:Reason ->
{stop, {shutdown, Reason}}
end;
supported_host_keys(server, KeyCb, Options) ->
- lists:foldl(fun(Type, Acc) ->
- case available_host_key(KeyCb, Type, Options) of
- {error, _} ->
- Acc;
- Alg ->
- [Alg | Acc]
- end
- end, [],
- %% Prefered alg last so no need to reverse
- ["ssh-dss", "ssh-rsa"]).
-extract_algs(false, _) ->
- false;
-extract_algs([],[]) ->
- false;
-extract_algs([], NewList) ->
- lists:reverse(NewList);
-extract_algs([H|T], NewList) ->
- case H of
- 'ssh-dss' ->
- extract_algs(T, ["ssh-dss"|NewList]);
- 'ssh-rsa' ->
- extract_algs(T, ["ssh-rsa"|NewList])
- end.
-available_host_key(KeyCb, "ssh-dss"= Alg, Opts) ->
- case KeyCb:host_key('ssh-dss', Opts) of
- {ok, _} ->
- Alg;
- Other ->
- Other
- end;
-available_host_key(KeyCb, "ssh-rsa" = Alg, Opts) ->
- case KeyCb:host_key('ssh-rsa', Opts) of
- {ok, _} ->
- Alg;
- Other ->
- Other
- end.
+ [atom_to_list(A) || A <- proplists:get_value(public_key,
+ proplists:get_value(preferred_algorithms,Options,[]),
+ ssh_transport:default_algorithms(public_key)
+ ),
+ available_host_key(KeyCb, A, Options)
+ ].
+
+%% Alg :: atom()
+available_host_key(KeyCb, Alg, Opts) ->
+ element(1, catch KeyCb:host_key(Alg, Opts)) == ok.
send_msg(Msg, #state{socket = Socket, transport_cb = Transport}) ->
Transport:send(Socket, Msg).
@@ -1257,7 +1378,7 @@ event(Event, StateName, State) ->
handle_disconnect(DisconnectMsg, State);
throw:{ErrorToDisplay, #ssh_msg_disconnect{} = DisconnectMsg} ->
handle_disconnect(DisconnectMsg, State, ErrorToDisplay);
- _:_ ->
+ _C:_Error ->
handle_disconnect(#ssh_msg_disconnect{code = error_code(StateName),
description = "Invalid state",
language = "en"}, State)
@@ -1273,7 +1394,6 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
#state{
role = Role,
starter = User,
- opts = Opts,
renegotiate = Renegotiation,
connection_state = Connection0} = State0, EncData)
when Byte == ?SSH_MSG_GLOBAL_REQUEST;
@@ -1290,41 +1410,57 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName,
Byte == ?SSH_MSG_CHANNEL_REQUEST;
Byte == ?SSH_MSG_CHANNEL_SUCCESS;
Byte == ?SSH_MSG_CHANNEL_FAILURE ->
- ConnectionMsg = ssh_message:decode(Msg),
- State1 = generate_event_new_state(State0, EncData),
- try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
- {{replies, Replies}, Connection} ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- {next_state, StateName, next_packet(State)};
- {noreply, Connection} ->
- {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
- {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
- Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- User ! {self(), not_connected, Reason},
- {stop, {shutdown, normal},
- next_packet(State#state{connection_state = Connection})};
- {disconnect, Reason, {{replies, Replies}, Connection}} ->
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ try
+ ssh_message:decode(Msg)
+ of
+ ConnectionMsg ->
+ State1 = generate_event_new_state(State0, EncData),
+ try ssh_connection:handle_msg(ConnectionMsg, Connection0, Role) of
+ {{replies, Replies0}, Connection} ->
+ if StateName == connected ->
+ Replies = Replies0,
+ State2 = State1;
+ true ->
+ {ConnReplies, Replies} =
+ lists:splitwith(fun not_connected_filter/1, Replies0),
+ Q = State1#state.event_queue ++ ConnReplies,
+ State2 = State1#state{ event_queue = Q }
+ end,
+ State = send_replies(Replies, State2#state{connection_state = Connection}),
+ {next_state, StateName, next_packet(State)};
+ {noreply, Connection} ->
+ {next_state, StateName, next_packet(State1#state{connection_state = Connection})};
+ {disconnect, {_, Reason}, {{replies, Replies}, Connection}} when
+ Role == client andalso ((StateName =/= connected) and (not Renegotiation)) ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ User ! {self(), not_connected, Reason},
+ {stop, {shutdown, normal},
+ next_packet(State#state{connection_state = Connection})};
+ {disconnect, _Reason, {{replies, Replies}, Connection}} ->
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, normal}, State#state{connection_state = Connection}}
+ catch
+ _:Error ->
+ {disconnect, _Reason, {{replies, Replies}, Connection}} =
+ ssh_connection:handle_msg(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "Internal error",
+ language = "en"}, Connection0, Role),
+ State = send_replies(Replies, State1#state{connection_state = Connection}),
+ {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ end
+
catch
- _:Error ->
- {disconnect, Reason, {{replies, Replies}, Connection}} =
- ssh_connection:handle_msg(
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
- description = "Internal error",
- language = "en"}, Connection0, Role),
- State = send_replies(Replies, State1#state{connection_state = Connection}),
- SSHOpts = proplists:get_value(ssh_opts, Opts),
- disconnect_fun(Reason, SSHOpts),
- {stop, {shutdown, Error}, State#state{connection_state = Connection}}
+ _:_ ->
+ handle_disconnect(
+ #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Bad packet received",
+ language = ""}, State0)
end;
generate_event(Msg, StateName, State0, EncData) ->
try
- Event = ssh_message:decode(Msg),
+ Event = ssh_message:decode(set_prefix_if_trouble(Msg,State0)),
State = generate_event_new_state(State0, EncData),
case Event of
#ssh_msg_kexinit{} ->
@@ -1334,7 +1470,7 @@ generate_event(Msg, StateName, State0, EncData) ->
event(Event, StateName, State)
end
catch
- _:_ ->
+ _C:_E ->
DisconnectMsg =
#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
description = "Encountered unexpected input",
@@ -1343,6 +1479,26 @@ generate_event(Msg, StateName, State0, EncData) ->
end.
+set_prefix_if_trouble(Msg = <<?BYTE(Op),_/binary>>, #state{ssh_params=SshParams})
+ when Op == 30;
+ Op == 31
+ ->
+ case catch atom_to_list(kex(SshParams)) of
+ "ecdh-sha2-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
+ "diffie-hellman-group-exchange-" ++ _ ->
+ <<"dh_gex",Msg/binary>>;
+ "diffie-hellman-group" ++ _ ->
+ <<"dh",Msg/binary>>;
+ _ ->
+ Msg
+ end;
+set_prefix_if_trouble(Msg, _) ->
+ Msg.
+
+kex(#ssh{algorithms=#alg{kex=Kex}}) -> Kex;
+kex(_) -> undefined.
+
handle_request(ChannelPid, ChannelId, Type, Data, WantReply, From,
#state{connection_state =
@@ -1437,6 +1593,7 @@ new_channel_id(#state{connection_state = #connection{channel_id_seed = Id} =
= State) ->
{Id, State#state{connection_state =
Connection#connection{channel_id_seed = Id + 1}}}.
+
generate_event_new_state(#state{ssh_params =
#ssh{recv_sequence = SeqNum0}
= Ssh} = State, EncData) ->
@@ -1467,66 +1624,43 @@ next_packet(#state{socket = Socket} = State) ->
State.
after_new_keys(#state{renegotiate = true} = State) ->
- {connected, State#state{renegotiate = false}};
+ State1 = State#state{renegotiate = false, event_queue = []},
+ lists:foldr(fun after_new_keys_events/2, {next_state, connected, State1}, State#state.event_queue);
after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = client} = Ssh0} = State) ->
{Msg, Ssh} = ssh_auth:service_request_msg(Ssh0),
send_msg(Msg, State),
- {userauth, State#state{ssh_params = Ssh}};
+ {next_state, service_request, State#state{ssh_params = Ssh}};
after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = server}} = State) ->
- {userauth, State}.
-
-handle_ssh_packet_data(RemainingSshPacketLen, DecData, EncData, StateName,
- State) ->
- EncSize = size(EncData),
- case RemainingSshPacketLen > EncSize of
- true ->
- {next_state, StateName,
- next_packet(State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData,
- undecoded_packet_length =
- RemainingSshPacketLen})};
- false ->
- handle_ssh_packet(RemainingSshPacketLen, StateName,
- State#state{decoded_data_buffer = DecData,
- encoded_data_buffer = EncData})
-
- end.
-
-handle_ssh_packet(Length, StateName, #state{decoded_data_buffer = DecData0,
- encoded_data_buffer = EncData0,
- ssh_params = Ssh0,
- transport_protocol = _Protocol,
- socket = _Socket} = State0) ->
- try
- {Ssh1, DecData, EncData, Mac} =
- ssh_transport:unpack(EncData0, Length, Ssh0),
- SshPacket = <<DecData0/binary, DecData/binary>>,
- case ssh_transport:is_valid_mac(Mac, SshPacket, Ssh1) of
- true ->
- PacketData = ssh_transport:msg_data(SshPacket),
- {Ssh1, Msg} = ssh_transport:decompress(Ssh1, PacketData),
- generate_event(Msg, StateName,
- State0#state{ssh_params = Ssh1,
- %% Important to be set for
- %% next_packet
- decoded_data_buffer = <<>>},
- EncData);
- false ->
- DisconnectMsg =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad mac",
- language = "en"},
- handle_disconnect(DisconnectMsg, State0)
- end
- catch _:_ ->
- Disconnect =
- #ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Bad input",
- language = "en"},
- handle_disconnect(Disconnect, State0)
- end.
+ {next_state, service_request, State}.
+
+after_new_keys_events({sync, _Event, From}, {stop, _Reason, _StateData}=Terminator) ->
+ gen_fsm:reply(From, {error, closed}),
+ Terminator;
+after_new_keys_events(_, {stop, _Reason, _StateData}=Terminator) ->
+ Terminator;
+after_new_keys_events({sync, Event, From}, {next_state, StateName, StateData}) ->
+ case handle_sync_event(Event, From, StateName, StateData) of
+ {reply, Reply, NextStateName, NewStateData} ->
+ gen_fsm:reply(From, Reply),
+ {next_state, NextStateName, NewStateData};
+ {next_state, NextStateName, NewStateData}->
+ {next_state, NextStateName, NewStateData};
+ {stop, Reason, Reply, NewStateData} ->
+ gen_fsm:reply(From, Reply),
+ {stop, Reason, NewStateData}
+ end;
+after_new_keys_events({event, Event}, {next_state, StateName, StateData}) ->
+ case handle_event(Event, StateName, StateData) of
+ {next_state, NextStateName, NewStateData}->
+ {next_state, NextStateName, NewStateData};
+ {stop, Reason, NewStateData} ->
+ {stop, Reason, NewStateData}
+ end;
+after_new_keys_events({connection_reply, _Data} = Reply, {StateName, State}) ->
+ NewState = send_replies([Reply], State),
+ {next_state, StateName, NewState}.
handle_disconnect(DisconnectMsg, State) ->
@@ -1537,12 +1671,14 @@ handle_disconnect(#ssh_msg_disconnect{} = DisconnectMsg, State, Error) ->
handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0, role = Role} = State0) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
+ disconnect_fun(Desc, State#state.opts),
{stop, {shutdown, Desc}, State#state{connection_state = Connection}}.
handle_disconnect(Type, #ssh_msg_disconnect{description = Desc} = Msg, #state{connection_state = Connection0,
role = Role} = State0, ErrorMsg) ->
{disconnect, _, {{replies, Replies}, Connection}} = ssh_connection:handle_msg(Msg, Connection0, Role),
State = send_replies(disconnect_replies(Type, Msg, Replies), State0),
+ disconnect_fun(Desc, State#state.opts),
{stop, {shutdown, {Desc, ErrorMsg}}, State#state{connection_state = Connection}}.
disconnect_replies(own, Msg, Replies) ->
@@ -1636,6 +1772,11 @@ log_error(Reason) ->
error_logger:error_report(Report),
"Internal error".
+not_connected_filter({connection_reply, _Data}) ->
+ true;
+not_connected_filter(_) ->
+ false.
+
send_replies([], State) ->
State;
send_replies([{connection_reply, Data} | Rest], #state{ssh_params = Ssh0} = State) ->
@@ -1656,6 +1797,8 @@ send_reply({flow_control, Cache, Channel, From, Msg}) ->
send_reply({flow_control, From, Msg}) ->
gen_fsm:reply(From, Msg).
+disconnect_fun({disconnect,Msg}, Opts) ->
+ disconnect_fun(Msg, Opts);
disconnect_fun(_, undefined) ->
ok;
disconnect_fun(Reason, Opts) ->
@@ -1666,6 +1809,15 @@ disconnect_fun(Reason, Opts) ->
catch Fun(Reason)
end.
+unexpected_fun(UnexpectedMessage, Opts, #ssh{peer={_,Peer}}) ->
+ case proplists:get_value(unexpectedfun, Opts) of
+ undefined ->
+ report;
+ Fun ->
+ catch Fun(UnexpectedMessage, Peer)
+ end.
+
+
check_cache(#state{opts = Opts} = State, Cache) ->
%% Check the number of entries in Cache
case proplists:get_value(size, ets:info(Cache)) of
diff --git a/lib/ssh/src/ssh_connection_sup.erl b/lib/ssh/src/ssh_connection_sup.erl
index c5abc8f23b..e8d0d49668 100644
--- a/lib/ssh/src/ssh_connection_sup.erl
+++ b/lib/ssh/src/ssh_connection_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_daemon_channel.erl b/lib/ssh/src/ssh_daemon_channel.erl
index ab3efbcaff..560e8246de 100644
--- a/lib/ssh/src/ssh_daemon_channel.erl
+++ b/lib/ssh/src/ssh_daemon_channel.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 5692138a8a..3e066c453d 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -51,8 +52,20 @@ host_key(Algorithm, Opts) ->
%% so probably we could hardcod Password = ignore, but
%% we keep it as an undocumented option for now.
Password = proplists:get_value(identity_pass_phrase(Algorithm), Opts, ignore),
- decode(File, Password).
-
+ case decode(File, Password) of
+ {ok,Key} ->
+ case {Key,Algorithm} of
+ {#'RSAPrivateKey'{}, 'ssh-rsa'} -> {ok,Key};
+ {#'DSAPrivateKey'{}, 'ssh-dss'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp256r1'}}, 'ecdsa-sha2-nistp256'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp384r1'}}, 'ecdsa-sha2-nistp384'} -> {ok,Key};
+ {#'ECPrivateKey'{parameters = {namedCurve, ?'secp521r1'}}, 'ecdsa-sha2-nistp521'} -> {ok,Key};
+ _ ->
+ {error,bad_keytype_in_file}
+ end;
+ Other ->
+ Other
+ end.
is_auth_key(Key, User,Opts) ->
case lookup_user_key(Key, User, Opts) of
@@ -80,16 +93,15 @@ user_key(Algorithm, Opts) ->
%% Internal functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-file_base_name('ssh-rsa') ->
- "ssh_host_rsa_key";
-file_base_name('ssh-dss') ->
- "ssh_host_dsa_key";
-file_base_name(_) ->
- "ssh_host_key".
+file_base_name('ssh-rsa' ) -> "ssh_host_rsa_key";
+file_base_name('ssh-dss' ) -> "ssh_host_dsa_key";
+file_base_name('ecdsa-sha2-nistp256') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp384') -> "ssh_host_ecdsa_key";
+file_base_name('ecdsa-sha2-nistp521') -> "ssh_host_ecdsa_key";
+file_base_name(_ ) -> "ssh_host_key".
decode(File, Password) ->
- try
- {ok, decode_ssh_file(read_ssh_file(File), Password)}
+ try {ok, decode_ssh_file(read_ssh_file(File), Password)}
catch
throw:Reason ->
{error, Reason};
@@ -209,29 +221,32 @@ do_lookup_host_key(KeyToMatch, Host, Alg, Opts) ->
{ok, Fd} ->
Res = lookup_host_key_fd(Fd, KeyToMatch, Host, Alg),
file:close(Fd),
- {ok, Res};
- {error, enoent} -> {error, not_found};
- Error -> Error
+ Res;
+ {error, enoent} ->
+ {error, not_found};
+ Error ->
+ Error
end.
-identity_key_filename('ssh-dss') ->
- "id_dsa";
-identity_key_filename('ssh-rsa') ->
- "id_rsa".
-
-identity_pass_phrase("ssh-dss") ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-dss') ->
- dsa_pass_phrase;
-identity_pass_phrase('ssh-rsa') ->
- rsa_pass_phrase;
-identity_pass_phrase("ssh-rsa") ->
- rsa_pass_phrase.
-
+identity_key_filename('ssh-dss' ) -> "id_dsa";
+identity_key_filename('ssh-rsa' ) -> "id_rsa";
+identity_key_filename('ecdsa-sha2-nistp256') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp384') -> "id_ecdsa";
+identity_key_filename('ecdsa-sha2-nistp521') -> "id_ecdsa".
+
+identity_pass_phrase("ssh-dss" ) -> dsa_pass_phrase;
+identity_pass_phrase("ssh-rsa" ) -> rsa_pass_phrase;
+identity_pass_phrase("ecdsa-sha2-"++_) -> ecdsa_pass_phrase;
+identity_pass_phrase(P) when is_atom(P) ->
+ identity_pass_phrase(atom_to_list(P)).
+
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, known_hosts) of
[{Key, Attributes}] ->
@@ -252,7 +267,7 @@ handle_host(Fd, KeyToMatch, Host, HostList, Key, KeyType) ->
Host1 = host_name(Host),
case lists:member(Host1, HostList) andalso key_match(Key, KeyType) of
true when KeyToMatch == Key ->
- Key;
+ {ok,Key};
_ ->
lookup_host_key_fd(Fd, KeyToMatch, Host, KeyType)
end.
@@ -266,6 +281,13 @@ key_match(#'RSAPublicKey'{}, 'ssh-rsa') ->
true;
key_match({_, #'Dss-Parms'{}}, 'ssh-dss') ->
true;
+key_match({#'ECPoint'{},{namedCurve,Curve}}, Alg) ->
+ case atom_to_list(Alg) of
+ "ecdsa-sha2-"++IdS ->
+ Curve == public_key:ssh_curvename2oid(list_to_binary(IdS));
+ _ ->
+ false
+ end;
key_match(_, _) ->
false.
@@ -292,6 +314,9 @@ lookup_user_key_fd(Fd, Key) ->
case io:get_line(Fd, '') of
eof ->
{error, not_found};
+ {error,Error} ->
+ %% Rare... For example NFS errors
+ {error,Error};
Line ->
case ssh_decode_line(Line, auth_keys) of
[{AuthKey, _}] ->
@@ -311,8 +336,18 @@ is_auth_key(Key, Key) ->
is_auth_key(_,_) ->
false.
-default_user_dir()->
- {ok,[[Home|_]]} = init:get_argument(home),
+
+default_user_dir() ->
+ try
+ default_user_dir(os:getenv("HOME"))
+ catch
+ _:_ ->
+ default_user_dir(init:get_argument(home))
+ end.
+
+default_user_dir({ok,[[Home|_]]}) ->
+ default_user_dir(Home);
+default_user_dir(Home) when is_list(Home) ->
UserDir = filename:join(Home, ".ssh"),
ok = filelib:ensure_dir(filename:join(UserDir, "dummy")),
{ok,Info} = file:read_file_info(UserDir),
diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl
index 30df32c4fd..4e6e25bc70 100644
--- a/lib/ssh/src/ssh_info.erl
+++ b/lib/ssh/src/ssh_info.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -79,7 +80,7 @@ print_clients(D) ->
print_client(D, {undefined,Pid,supervisor,[ssh_connection_handler]}) ->
{{Local,Remote},_Str} = ssh_connection_handler:get_print_info(Pid),
- io:format(D, " Local=~s Remote=~s~n",[fmt_host_port(Local),fmt_host_port(Remote)]);
+ io:format(D, " Local=~s Remote=~s ConnectionRef=~p~n",[fmt_host_port(Local),fmt_host_port(Remote),Pid]);
print_client(D, Other) ->
io:format(D, " [[Other 1: ~p]]~n",[Other]).
@@ -134,10 +135,11 @@ walk_sups(D, StartPid) ->
io:format(D, "Start at ~p, ~s.~n",[StartPid,dead_or_alive(StartPid)]),
walk_sups(D, children(StartPid), _Indent=?inc(0)).
-walk_sups(D, [H={_,Pid,SupOrWorker,_}|T], Indent) ->
+walk_sups(D, [H={_,Pid,_,_}|T], Indent) ->
indent(D, Indent), io:format(D, '~200p ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]),
- case SupOrWorker of
- supervisor -> walk_sups(D, children(Pid), ?inc(Indent));
+ case H of
+ {_,_,supervisor,[ssh_connection_handler]} -> ok;
+ {_,Pid,supervisor,_} -> walk_sups(D, children(Pid), ?inc(Indent));
_ -> ok
end,
walk_sups(D, T, Indent);
@@ -187,7 +189,7 @@ line(D, Len, Char) ->
datetime() ->
- {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(now()),
+ {{YYYY,MM,DD}, {H,M,S}} = calendar:now_to_universal_time(erlang:timestamp()),
lists:flatten(io_lib:format('~4w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w UTC',[YYYY,MM,DD, H,M,S])).
diff --git a/lib/ssh/src/ssh_io.erl b/lib/ssh/src/ssh_io.erl
index 97e2dee27a..a5e627fdb3 100644
--- a/lib/ssh/src/ssh_io.erl
+++ b/lib/ssh/src/ssh_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_math.erl b/lib/ssh/src/ssh_math.erl
deleted file mode 100644
index 569c1cb58d..0000000000
--- a/lib/ssh/src/ssh_math.erl
+++ /dev/null
@@ -1,41 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%%
-
-%%% Description: SSH math utilities
-
--module(ssh_math).
-
--export([ipow/3]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%
-%% INTEGER utils
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% calculate A^B mod M
-ipow(A, B, M) when M > 0, B >= 0 ->
- crypto:bytes_to_integer(crypto:mod_pow(A, B, M)).
-
-
-
-
-
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 66e7717095..b6c4496be2 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2013-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -29,7 +30,7 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([encode/1, decode/1, encode_host_key/1, decode_keyboard_interactive_prompts/2]).
+-export([encode/1, decode/1, decode_keyboard_interactive_prompts/2]).
encode(#ssh_msg_global_request{
name = Name,
@@ -226,8 +227,8 @@ encode(#ssh_msg_kexdh_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_kex_dh_gex_request{
@@ -236,7 +237,7 @@ encode(#ssh_msg_kex_dh_gex_request{
max = Max
}) ->
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REQUEST, Min, N, Max],
- [byte, uint32, uint32, uint32, uint32]);
+ [byte, uint32, uint32, uint32]);
encode(#ssh_msg_kex_dh_gex_request_old{n = N}) ->
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REQUEST_OLD, N],
[byte, uint32]);
@@ -254,9 +255,17 @@ encode(#ssh_msg_kex_dh_gex_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
- EncSign = encode_sign(Key, Signature),
- ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Signature),
+ ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
+
+encode(#ssh_msg_kex_ecdh_init{q_c = Q_c}) ->
+ ssh_bits:encode([?SSH_MSG_KEX_ECDH_INIT, Q_c], [byte, mpint]);
+
+encode(#ssh_msg_kex_ecdh_reply{public_host_key = Key, q_s = Q_s, h_sig = Sign}) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ EncSign = encode_signature(Key, Sign),
+ ssh_bits:encode([?SSH_MSG_KEX_ECDH_REPLY, EncKey, Q_s, EncSign], [byte, binary, mpint, binary]);
encode(#ssh_msg_ignore{data = Data}) ->
ssh_bits:encode([?SSH_MSG_IGNORE, Data], [byte, string]);
@@ -271,8 +280,7 @@ encode(#ssh_msg_debug{always_display = Bool,
%% Connection Messages
-decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?UINT32(Len), Name:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_GLOBAL_REQUEST), ?DEC_BIN(Name,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_global_request{
name = Name,
want_reply = erl_boolean(Bool),
@@ -283,8 +291,7 @@ decode(<<?BYTE(?SSH_MSG_REQUEST_SUCCESS), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_REQUEST_FAILURE)>>) ->
#ssh_msg_request_failure{};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN),
- ?UINT32(Len), Type:Len/binary,
- ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
+ ?DEC_BIN(Type,__0), ?UINT32(Sender), ?UINT32(Window), ?UINT32(Max),
Data/binary>>) ->
#ssh_msg_channel_open{
channel_type = binary_to_list(Type),
@@ -304,7 +311,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_CONFIRMATION), ?UINT32(Recipient), ?UINT32(
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_OPEN_FAILURE), ?UINT32(Recipient), ?UINT32(Reason),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary >>) ->
+ ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1) >> ) ->
#ssh_msg_channel_open_failure{
recipient_channel = Recipient,
reason = Reason,
@@ -317,13 +324,13 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_WINDOW_ADJUST), ?UINT32(Recipient), ?UINT32(Byte
bytes_to_add = Bytes
};
-decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_CHANNEL_DATA), ?UINT32(Recipient), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_data{
recipient_channel = Recipient,
data = Data
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_EXTENDED_DATA), ?UINT32(Recipient),
- ?UINT32(DataType), ?UINT32(Len), Data:Len/binary>>) ->
+ ?UINT32(DataType), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_channel_extended_data{
recipient_channel = Recipient,
data_type_code = DataType,
@@ -338,8 +345,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_CLOSE), ?UINT32(Recipient)>>) ->
recipient_channel = Recipient
};
decode(<<?BYTE(?SSH_MSG_CHANNEL_REQUEST), ?UINT32(Recipient),
- ?UINT32(Len), RequestType:Len/binary,
- ?BYTE(Bool), Data/binary>>) ->
+ ?DEC_BIN(RequestType,__0), ?BYTE(Bool), Data/binary>>) ->
#ssh_msg_channel_request{
recipient_channel = Recipient,
request_type = unicode:characters_to_list(RequestType),
@@ -357,9 +363,7 @@ decode(<<?BYTE(?SSH_MSG_CHANNEL_FAILURE), ?UINT32(Recipient)>>) ->
%%% Auth Messages
decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
- ?UINT32(Len0), User:Len0/binary,
- ?UINT32(Len1), Service:Len1/binary,
- ?UINT32(Len2), Method:Len2/binary,
+ ?DEC_BIN(User,__0), ?DEC_BIN(Service,__1), ?DEC_BIN(Method,__2),
Data/binary>>) ->
#ssh_msg_userauth_request{
user = unicode:characters_to_list(User),
@@ -369,7 +373,7 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_REQUEST),
};
decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
- ?UINT32(Len0), Auths:Len0/binary,
+ ?DEC_BIN(Auths,__0),
?BYTE(Bool)>>) ->
#ssh_msg_userauth_failure {
authentications = unicode:characters_to_list(Auths),
@@ -379,16 +383,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_FAILURE),
decode(<<?BYTE(?SSH_MSG_USERAUTH_SUCCESS)>>) ->
#ssh_msg_userauth_success{};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER),
- ?UINT32(Len0), Banner:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_BANNER), ?DEC_BIN(Banner,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_banner{
message = Banner,
language = Lang
};
-decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
- ?UINT32(Len1), Inst:Len1/binary, ?UINT32(Len2), Lang:Len2/binary,
+decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST),
+ ?DEC_BIN(Name,__0), ?DEC_BIN(Inst,__1), ?DEC_BIN(Lang,__2),
?UINT32(NumPromtps), Data/binary>>) ->
#ssh_msg_userauth_info_request{
name = Name,
@@ -398,15 +400,14 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_REQUEST), ?UINT32(Len0), Name:Len0/binary,
data = Data};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?UINT32(Len0), Prompt:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PASSWD_CHANGEREQ), ?DEC_BIN(Prompt,__0), ?DEC_BIN(Lang,__1) >>) ->
#ssh_msg_userauth_passwd_changereq{
prompt = Prompt,
languge = Lang
};
%%% Unhandled message, also masked by same 1:st byte value as ?SSH_MSG_USERAUTH_INFO_REQUEST:
-decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?UINT32(Len), Alg:Len/binary, KeyBlob/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_USERAUTH_PK_OK), ?DEC_BIN(Alg,__0), KeyBlob/binary>>) ->
#ssh_msg_userauth_pk_ok{
algorithm_name = Alg,
key_blob = KeyBlob
@@ -421,47 +422,71 @@ decode(<<?BYTE(?SSH_MSG_USERAUTH_INFO_RESPONSE), ?UINT32(Num), Data/binary>>) ->
decode(<<?BYTE(?SSH_MSG_KEXINIT), Cookie:128, Data/binary>>) ->
decode_kex_init(Data, [Cookie, ssh_msg_kexinit], 10);
-decode(<<?BYTE(?SSH_MSG_KEXDH_INIT), ?UINT32(Len), E:Len/binary>>) ->
- #ssh_msg_kexdh_init{e = erlint(Len, E)
+decode(<<"dh",?BYTE(?SSH_MSG_KEXDH_INIT), ?DEC_MPINT(E,__0)>>) ->
+ #ssh_msg_kexdh_init{e = E
};
+
+decode(<<"dh", ?BYTE(?SSH_MSG_KEXDH_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
+ #ssh_msg_kexdh_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ f = F,
+ h_sig = decode_signature(Hashsign)
+ };
+
decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST), ?UINT32(Min), ?UINT32(N), ?UINT32(Max)>>) ->
#ssh_msg_kex_dh_gex_request{
min = Min,
n = N,
max = Max
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST_OLD), ?UINT32(N)>>) ->
+
+decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_REQUEST_OLD), ?UINT32(N)>>) ->
#ssh_msg_kex_dh_gex_request_old{
n = N
};
-decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP),
- ?UINT32(Len0), Prime:Len0/big-signed-integer-unit:8,
- ?UINT32(Len1), Generator:Len1/big-signed-integer-unit:8>>) ->
+
+decode(<<"dh_gex",?BYTE(?SSH_MSG_KEX_DH_GEX_GROUP), ?DEC_MPINT(Prime,__0), ?DEC_MPINT(Generator,__1) >>) ->
#ssh_msg_kex_dh_gex_group{
p = Prime,
g = Generator
};
-decode(<<?BYTE(?SSH_MSG_KEXDH_REPLY), ?UINT32(Len0), Key:Len0/binary,
- ?UINT32(Len1), F:Len1/binary,
- ?UINT32(Len2), Hashsign:Len2/binary>>) ->
- #ssh_msg_kexdh_reply{
- public_host_key = decode_host_key(Key),
- f = erlint(Len1, F),
- h_sig = decode_sign(Hashsign)
+
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_INIT), ?DEC_MPINT(E,__0)>>) ->
+ #ssh_msg_kex_dh_gex_init{
+ e = E
+ };
+
+decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
+ #ssh_msg_kex_dh_gex_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ f = F,
+ h_sig = decode_signature(Hashsign)
};
-decode(<<?SSH_MSG_SERVICE_REQUEST, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_INIT), ?DEC_MPINT(Q_c,__0)>>) ->
+ #ssh_msg_kex_ecdh_init{
+ q_c = Q_c
+ };
+
+decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_REPLY),
+ ?DEC_BIN(Key,__1), ?DEC_MPINT(Q_s,__2), ?DEC_BIN(Sig,__3)>>) ->
+ #ssh_msg_kex_ecdh_reply{
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
+ q_s = Q_s,
+ h_sig = decode_signature(Sig)
+ };
+
+decode(<<?SSH_MSG_SERVICE_REQUEST, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_request{
name = unicode:characters_to_list(Service)
};
-decode(<<?SSH_MSG_SERVICE_ACCEPT, ?UINT32(Len0), Service:Len0/binary>>) ->
+decode(<<?SSH_MSG_SERVICE_ACCEPT, ?DEC_BIN(Service,__0)>>) ->
#ssh_msg_service_accept{
name = unicode:characters_to_list(Service)
};
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary, ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -469,8 +494,7 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
};
%% Accept bad disconnects from ancient openssh clients that doesn't send language tag. Use english as a work-around.
-decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
- ?UINT32(Len0), Desc:Len0/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code), ?DEC_BIN(Desc,__0)>>) ->
#ssh_msg_disconnect{
code = Code,
description = unicode:characters_to_list(Desc),
@@ -480,21 +504,25 @@ decode(<<?BYTE(?SSH_MSG_DISCONNECT), ?UINT32(Code),
decode(<<?SSH_MSG_NEWKEYS>>) ->
#ssh_msg_newkeys{};
-decode(<<?BYTE(?SSH_MSG_IGNORE), ?UINT32(Len), Data:Len/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_IGNORE), ?DEC_BIN(Data,__0)>>) ->
#ssh_msg_ignore{data = Data};
decode(<<?BYTE(?SSH_MSG_UNIMPLEMENTED), ?UINT32(Seq)>>) ->
#ssh_msg_unimplemented{sequence = Seq};
-decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?UINT32(Len0), Msg:Len0/binary,
- ?UINT32(Len1), Lang:Len1/binary>>) ->
+decode(<<?BYTE(?SSH_MSG_DEBUG), ?BYTE(Bool), ?DEC_BIN(Msg,__0), ?DEC_BIN(Lang,__1)>>) ->
#ssh_msg_debug{always_display = erl_boolean(Bool),
message = Msg,
language = Lang}.
+%%%================================================================
+%%%
+%%% Helper functions
+%%%
+
decode_keyboard_interactive_prompts(<<>>, Acc) ->
lists:reverse(Acc);
-decode_keyboard_interactive_prompts(<<?UINT32(Len), Prompt:Len/binary, ?BYTE(Bool), Bin/binary>>,
+decode_keyboard_interactive_prompts(<<?DEC_BIN(Prompt,__0), ?BYTE(Bool), Bin/binary>>,
Acc) ->
decode_keyboard_interactive_prompts(Bin, [{Prompt, erl_boolean(Bool)} | Acc]).
@@ -510,45 +538,25 @@ decode_kex_init(<<?BYTE(Bool)>>, Acc, 0) ->
%% See rfc 4253 7.1
X = 0,
list_to_tuple(lists:reverse([X, erl_boolean(Bool) | Acc]));
-decode_kex_init(<<?UINT32(Len), Data:Len/binary, Rest/binary>>, Acc, N) ->
+decode_kex_init(<<?DEC_BIN(Data,__0), Rest/binary>>, Acc, N) ->
Names = string:tokens(unicode:characters_to_list(Data), ","),
decode_kex_init(Rest, [Names | Acc], N -1).
-erlint(MPIntSize, MPIntValue) ->
- Bits = MPIntSize * 8,
- <<Integer:Bits/integer>> = MPIntValue,
- Integer.
-decode_sign(<<?UINT32(Len), _Alg:Len/binary, ?UINT32(_), Signature/binary>>) ->
+%%%================================================================
+%%%
+%%% Signature decode/encode
+%%%
+
+decode_signature(<<?DEC_BIN(_Alg,__0), ?UINT32(_), Signature/binary>>) ->
Signature.
-decode_host_key(<<?UINT32(Len), Alg:Len/binary, Rest/binary>>) ->
- decode_host_key(Alg, Rest).
-
-decode_host_key(<<"ssh-rsa">>, <<?UINT32(Len0), E:Len0/binary,
- ?UINT32(Len1), N:Len1/binary>>) ->
- #'RSAPublicKey'{publicExponent = erlint(Len0, E),
- modulus = erlint(Len1, N)};
-
-decode_host_key(<<"ssh-dss">>,
- <<?UINT32(Len0), P:Len0/binary,
- ?UINT32(Len1), Q:Len1/binary,
- ?UINT32(Len2), G:Len2/binary,
- ?UINT32(Len3), Y:Len3/binary>>) ->
- {erlint(Len3, Y), #'Dss-Parms'{p = erlint(Len0, P), q = erlint(Len1, Q),
- g = erlint(Len2, G)}}.
-
-encode_host_key(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]);
-encode_host_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]).
-encode_sign(#'RSAPrivateKey'{}, Signature) ->
+
+encode_signature(#'RSAPublicKey'{}, Signature) ->
ssh_bits:encode(["ssh-rsa", Signature],[string, binary]);
-encode_sign(#'DSAPrivateKey'{}, Signature) ->
- ssh_bits:encode(["ssh-dss", Signature],[string, binary]).
+encode_signature({_, #'Dss-Parms'{}}, Signature) ->
+ ssh_bits:encode(["ssh-dss", Signature],[string, binary]);
+encode_signature({#'ECPoint'{}, {namedCurve,OID}}, Signature) ->
+ CurveName = public_key:oid2ssh_curvename(OID),
+ ssh_bits:encode([<<"ecdsa-sha2-",CurveName/binary>>, Signature], [binary,binary]).
+
diff --git a/lib/ssh/src/ssh_no_io.erl b/lib/ssh/src/ssh_no_io.erl
index 825a0d4af5..e8d1afd0ed 100644
--- a/lib/ssh/src/ssh_no_io.erl
+++ b/lib/ssh/src/ssh_no_io.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_server_key.erl b/lib/ssh/src/ssh_server_key.erl
index 8140114990..4ab326374a 100644
--- a/lib/ssh/src/ssh_server_key.erl
+++ b/lib/ssh/src/ssh_server_key.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_server_key_api.erl b/lib/ssh/src/ssh_server_key_api.erl
index 4fd660ecb5..7c05d82c03 100644
--- a/lib/ssh/src/ssh_server_key_api.erl
+++ b/lib/ssh/src/ssh_server_key_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 613f8f25b2..dbacf730cc 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -111,7 +112,7 @@ start_channel(Cm, Opts) when is_pid(Cm) ->
TimeOut
end;
{error, Reason} ->
- {error, Reason};
+ {error, format_channel_start_error(Reason)};
ignore ->
{error, ignore}
end;
@@ -136,7 +137,7 @@ start_channel(Host, Port, Opts) ->
TimeOut
end;
{error, Reason} ->
- {error, Reason};
+ {error, format_channel_start_error(Reason)};
ignore ->
{error, ignore}
end;
@@ -438,7 +439,7 @@ write_file(Pid, Name, List) ->
write_file(Pid, Name, List, ?FILEOP_TIMEOUT).
write_file(Pid, Name, List, FileOpTimeout) when is_list(List) ->
- write_file(Pid, Name, unicode:characters_to_binary(List), FileOpTimeout);
+ write_file(Pid, Name, list_to_binary(List), FileOpTimeout);
write_file(Pid, Name, Bin, FileOpTimeout) ->
case open(Pid, Name, [write, binary], FileOpTimeout) of
{ok, Handle} ->
@@ -491,9 +492,9 @@ init([Cm, ChannelId, Options]) ->
inf = new_inf(),
opts = Options}};
failure ->
- {stop, "server failed to start sftp subsystem"};
+ {stop, {shutdown, "server failed to start sftp subsystem"}};
Error ->
- {stop, Error}
+ {stop, {shutdown, Error}}
end.
%%--------------------------------------------------------------------
@@ -508,12 +509,12 @@ init([Cm, ChannelId, Options]) ->
%%--------------------------------------------------------------------
handle_call({{timeout, infinity}, wait_for_version_negotiation}, From,
#state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) ->
- {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}};
+ {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, undefined}}}};
handle_call({{timeout, Timeout}, wait_for_version_negotiation}, From,
#state{xf = #ssh_xfer{vsn = undefined} = Xf} = State) ->
- timer:send_after(Timeout, {timeout, undefined, From}),
- {noreply, State#state{xf = Xf#ssh_xfer{vsn = From}}};
+ TRef = erlang:send_after(Timeout, self(), {timeout, undefined, From}),
+ {noreply, State#state{xf = Xf#ssh_xfer{vsn = {wait, From, TRef}}}};
handle_call({_, wait_for_version_negotiation}, _, State) ->
{reply, ok, State};
@@ -610,8 +611,7 @@ do_handle_call({pread,Async,Handle,At,Length}, From, State) ->
fun({ok,Data}, State2) ->
case get_mode(Handle, State2) of
binary -> {{ok,Data}, State2};
- text ->
- {{ok,unicode:characters_to_list(Data)}, State2}
+ text -> {{ok,binary_to_list(Data)}, State2}
end;
(Rep, State2) ->
{Rep, State2}
@@ -865,7 +865,12 @@ do_handle_reply(#state{xf = Xf} = State,
case Xf#ssh_xfer.vsn of
undefined ->
ok;
- From ->
+ {wait, From, TRef} ->
+ if is_reference(TRef) ->
+ erlang:cancel_timer(TRef);
+ true ->
+ ok
+ end,
ssh_channel:reply(From, ok)
end,
State#state{xf = Xf#ssh_xfer{vsn = Version, ext = Ext}, rep_buf = Rest};
@@ -1412,3 +1417,8 @@ open_buf1(Pid, BufInfo0, FileOpTimeout, CryptoState, ChunkSize) ->
BufHandle = make_ref(),
call(Pid, {put_bufinf,BufHandle,BufInfo}, FileOpTimeout),
{ok,BufHandle}.
+
+format_channel_start_error({shutdown, Reason}) ->
+ Reason;
+format_channel_start_error(Reason) ->
+ Reason.
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index 04ae6b11e2..819cba697e 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -29,6 +30,7 @@
-include("ssh.hrl").
-include("ssh_xfer.hrl").
+-include("ssh_connect.hrl"). %% For ?DEFAULT_PACKET_SIZE and ?DEFAULT_WINDOW_SIZE
%%--------------------------------------------------------------------
%% External exports
@@ -46,6 +48,7 @@
file_handler, % atom() - callback module
file_state, % state for the file callback module
max_files, % integer >= 0 max no files sent during READDIR
+ options, % from the subsystem declaration
handles % list of open handles
%% handle is either {<int>, directory, {Path, unread|eof}} or
%% {<int>, file, {Path, IoDevice}}
@@ -120,6 +123,7 @@ init(Options) ->
MaxLength = proplists:get_value(max_files, Options, 0),
Vsn = proplists:get_value(sftpd_vsn, Options, 5),
{ok, State#state{cwd = CWD, root = Root, max_files = MaxLength,
+ options = Options,
handles = [], pending = <<>>,
xf = #ssh_xfer{vsn = Vsn, ext = []}}}.
@@ -163,7 +167,9 @@ handle_ssh_msg({ssh_cm, _, {exit_status, ChannelId, Status}}, State) ->
%% Description: Handles other messages
%%--------------------------------------------------------------------
handle_msg({ssh_channel_up, ChannelId, ConnectionManager},
- #state{xf =Xf} = State) ->
+ #state{xf = Xf,
+ options = Options} = State) ->
+ maybe_increase_recv_window(ConnectionManager, ChannelId, Options),
{ok, State#state{xf = Xf#ssh_xfer{cm = ConnectionManager,
channel = ChannelId}}}.
@@ -933,3 +939,18 @@ rename(Path, Path2, ReqId, State0) ->
{Status, FS1} = FileMod:rename(Path, Path2, FS0),
State1 = State0#state{file_state = FS1},
send_status(Status, ReqId, State1).
+
+
+maybe_increase_recv_window(ConnectionManager, ChannelId, Options) ->
+ WantedRecvWindowSize =
+ proplists:get_value(recv_window_size, Options, 1000000),
+ NumPkts = WantedRecvWindowSize div ?DEFAULT_PACKET_SIZE,
+ Increment = NumPkts*?DEFAULT_PACKET_SIZE - ?DEFAULT_WINDOW_SIZE,
+
+ if
+ Increment > 0 ->
+ ssh_connection:adjust_window(ConnectionManager, ChannelId,
+ Increment);
+ Increment =< 0 ->
+ do_nothing
+ end.
diff --git a/lib/ssh/src/ssh_sftpd_file.erl b/lib/ssh/src/ssh_sftpd_file.erl
index 91ba228e38..a287e8891b 100644
--- a/lib/ssh/src/ssh_sftpd_file.erl
+++ b/lib/ssh/src/ssh_sftpd_file.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_sftpd_file_api.erl b/lib/ssh/src/ssh_sftpd_file_api.erl
index 83d90907f5..c61d4e7ecf 100644
--- a/lib/ssh/src/ssh_sftpd_file_api.erl
+++ b/lib/ssh/src/ssh_sftpd_file_api.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_shell.erl b/lib/ssh/src/ssh_shell.erl
index 8031450617..22ad4da948 100644
--- a/lib/ssh/src/ssh_shell.erl
+++ b/lib/ssh/src/ssh_shell.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2009-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_subsystem_sup.erl b/lib/ssh/src/ssh_subsystem_sup.erl
index e8855b09ac..ebe33ec7da 100644
--- a/lib/ssh/src/ssh_subsystem_sup.erl
+++ b/lib/ssh/src/ssh_subsystem_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_sup.erl b/lib/ssh/src/ssh_sup.erl
index 6d2b9c107d..649ea00a06 100644
--- a/lib/ssh/src/ssh_sup.erl
+++ b/lib/ssh/src/ssh_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl
index 660fe8bb65..18a5d8071a 100644
--- a/lib/ssh/src/ssh_system_sup.erl
+++ b/lib/ssh/src/ssh_system_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -28,13 +29,15 @@
-behaviour(supervisor).
+-include("ssh.hrl").
+
-export([start_link/1, stop_listener/1,
- stop_listener/2, stop_system/1,
- stop_system/2, system_supervisor/2,
+ stop_listener/3, stop_system/1,
+ stop_system/3, system_supervisor/3,
subsystem_supervisor/1, channel_supervisor/1,
connection_supervisor/1,
- acceptor_supervisor/1, start_subsystem/2, restart_subsystem/2,
- restart_acceptor/2, stop_subsystem/2]).
+ acceptor_supervisor/1, start_subsystem/2, restart_subsystem/3,
+ restart_acceptor/3, stop_subsystem/2]).
%% Supervisor callback
-export([init/1]).
@@ -45,14 +48,15 @@
start_link(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- Name = make_name(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = make_name(Address, Port, Profile),
supervisor:start_link({local, Name}, ?MODULE, [ServerOpts]).
stop_listener(SysSup) ->
stop_acceptor(SysSup).
-stop_listener(Address, Port) ->
- Name = make_name(Address, Port),
+stop_listener(Address, Port, Profile) ->
+ Name = make_name(Address, Port, Profile),
stop_acceptor(whereis(Name)).
stop_system(SysSup) ->
@@ -60,12 +64,12 @@ stop_system(SysSup) ->
spawn(fun() -> sshd_sup:stop_child(Name) end),
ok.
-stop_system(Address, Port) ->
- spawn(fun() -> sshd_sup:stop_child(Address, Port) end),
+stop_system(Address, Port, Profile) ->
+ spawn(fun() -> sshd_sup:stop_child(Address, Port, Profile) end),
ok.
-system_supervisor(Address, Port) ->
- Name = make_name(Address, Port),
+system_supervisor(Address, Port, Profile) ->
+ Name = make_name(Address, Port, Profile),
whereis(Name).
subsystem_supervisor(SystemSup) ->
@@ -103,9 +107,9 @@ stop_subsystem(SystemSup, SubSys) ->
end.
-restart_subsystem(Address, Port) ->
- SysSupName = make_name(Address, Port),
- SubSysName = id(ssh_subsystem_sup, Address, Port),
+restart_subsystem(Address, Port, Profile) ->
+ SysSupName = make_name(Address, Port, Profile),
+ SubSysName = id(ssh_subsystem_sup, Address, Port, Profile),
case supervisor:terminate_child(SysSupName, SubSysName) of
ok ->
supervisor:restart_child(SysSupName, SubSysName);
@@ -113,9 +117,9 @@ restart_subsystem(Address, Port) ->
Error
end.
-restart_acceptor(Address, Port) ->
- SysSupName = make_name(Address, Port),
- AcceptorName = id(ssh_acceptor_sup, Address, Port),
+restart_acceptor(Address, Port, Profile) ->
+ SysSupName = make_name(Address, Port, Profile),
+ AcceptorName = id(ssh_acceptor_sup, Address, Port, Profile),
supervisor:restart_child(SysSupName, AcceptorName).
%%%=========================================================================
@@ -137,7 +141,8 @@ child_specs(ServerOpts) ->
ssh_acceptor_child_spec(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
Port = proplists:get_value(port, ServerOpts),
- Name = id(ssh_acceptor_sup, Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(ssh_acceptor_sup, Address, Port, Profile),
StartFunc = {ssh_acceptor_sup, start_link, [ServerOpts]},
Restart = transient,
Shutdown = infinity,
@@ -155,12 +160,23 @@ ssh_subsystem_child_spec(ServerOpts) ->
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Sup, Address, Port) ->
- {Sup, Address, Port}.
-
-make_name(Address, Port) ->
- list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_sup",
- [Address, Port]))).
+id(Sup, Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {Sup, any, Port, Profile};
+ false ->
+ {Sup, Address, Port, Profile}
+ end.
+
+make_name(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
+ [any, Port, Profile])));
+ false ->
+ list_to_atom(lists:flatten(io_lib:format("ssh_system_~p_~p_~p_sup",
+ [Address, Port, Profile])))
+ end.
ssh_subsystem_sup([{_, Child, _, [ssh_subsystem_sup]} | _]) ->
Child;
@@ -178,3 +194,4 @@ stop_acceptor(Sup) ->
supervisor:which_children(Sup)],
supervisor:terminate_child(AcceptorSup, Name).
+
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 6c0873fd9e..18037b8461 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -30,18 +31,109 @@
-include("ssh.hrl").
-export([versions/2, hello_version_msg/1]).
--export([next_seqnum/1, decrypt_first_block/2, decrypt_blocks/3,
- is_valid_mac/3,
+-export([next_seqnum/1,
+ supported_algorithms/0, supported_algorithms/1,
+ default_algorithms/0, default_algorithms/1,
+ handle_packet_part/4,
handle_hello_version/1,
key_exchange_init_msg/1,
key_init/3, new_keys_message/1,
handle_kexinit_msg/3, handle_kexdh_init/2,
- handle_kex_dh_gex_group/2, handle_kex_dh_gex_reply/2,
+ handle_kex_dh_gex_group/2, handle_kex_dh_gex_init/2, handle_kex_dh_gex_reply/2,
handle_new_keys/2, handle_kex_dh_gex_request/2,
handle_kexdh_reply/2,
- unpack/3, decompress/2, ssh_packet/2, pack/2, msg_data/1,
+ handle_kex_ecdh_init/2,
+ handle_kex_ecdh_reply/2,
+ extract_public_key/1,
+ ssh_packet/2, pack/2,
sign/3, verify/4]).
+%%% For test suites
+-export([pack/3]).
+-export([decompress/2, decrypt_blocks/3, is_valid_mac/3 ]). % FIXME: remove
+
+%%%----------------------------------------------------------------------------
+%%%
+%%% There is a difference between supported and default algorithms. The
+%%% SUPPORTED algorithms can be handled (maybe untested...). The DEFAULT ones
+%%% are announced in ssh_msg_kexinit and in ssh:default_algorithms/0 to the
+%%% user.
+%%%
+%%% A supported algorithm can be requested in the option 'preferred_algorithms',
+%%% but may give unexpected results before being promoted to default.
+%%%
+%%% This makes it possible to add experimental algorithms (in supported_algorithms)
+%%% and test them without letting the default users know about them.
+%%%
+
+default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].
+
+algo_classes() -> [kex, public_key, cipher, mac, compression].
+
+
+default_algorithms(cipher) ->
+ supported_algorithms(cipher, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
+default_algorithms(mac) ->
+ supported_algorithms(mac, same(['AEAD_AES_128_GCM',
+ 'AEAD_AES_256_GCM']));
+default_algorithms(Alg) ->
+ supported_algorithms(Alg, []).
+
+
+supported_algorithms() -> [{K,supported_algorithms(K)} || K <- algo_classes()].
+
+supported_algorithms(kex) ->
+ select_crypto_supported(
+ [
+ {'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
+ {'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]},
+ {'diffie-hellman-group14-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
+ {'diffie-hellman-group-exchange-sha1', [{public_keys,dh}, {hashs,sha}]},
+ {'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
+ {'diffie-hellman-group1-sha1', [{public_keys,dh}, {hashs,sha}]}
+ ]);
+supported_algorithms(public_key) ->
+ select_crypto_supported(
+ [{'ecdsa-sha2-nistp256', [{public_keys,ecdsa}, {hashs,sha256}, {ec_curve,secp256r1}]},
+ {'ecdsa-sha2-nistp384', [{public_keys,ecdsa}, {hashs,sha384}, {ec_curve,secp384r1}]},
+ {'ecdsa-sha2-nistp521', [{public_keys,ecdsa}, {hashs,sha512}, {ec_curve,secp521r1}]},
+ {'ssh-rsa', [{public_keys,rsa}, {hashs,sha} ]},
+ {'ssh-dss', [{public_keys,dss}, {hashs,sha} ]}
+ ]);
+
+supported_algorithms(cipher) ->
+ same(
+ select_crypto_supported(
+ [{'aes256-ctr', [{ciphers,{aes_ctr,256}}]},
+ {'aes192-ctr', [{ciphers,{aes_ctr,192}}]},
+ {'aes128-ctr', [{ciphers,{aes_ctr,128}}]},
+ {'aes128-cbc', [{ciphers,aes_cbc128}]},
+ {'[email protected]', [{ciphers,{aes_gcm,128}}]},
+ {'[email protected]', [{ciphers,{aes_gcm,256}}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]},
+ {'3des-cbc', [{ciphers,des3_cbc}]}
+ ]
+ ));
+supported_algorithms(mac) ->
+ same(
+ select_crypto_supported(
+ [{'hmac-sha2-256', [{hashs,sha256}]},
+ {'hmac-sha2-512', [{hashs,sha512}]},
+ {'hmac-sha1', [{hashs,sha}]},
+ {'AEAD_AES_128_GCM', [{ciphers,{aes_gcm,128}}]},
+ {'AEAD_AES_256_GCM', [{ciphers,{aes_gcm,256}}]}
+ ]
+ ));
+supported_algorithms(compression) ->
+ same(['none',
+ 'zlib'
+ ]).
+
+%%%----------------------------------------------------------------------------
versions(client, Options)->
Vsn = proplists:get_value(vsn, Options, ?DEFAULT_CLIENT_VERSION),
{Vsn, format_version(Vsn, software_version(Options))};
@@ -70,7 +162,7 @@ ssh_vsn() ->
_:_ -> ""
end.
-random_id(Nlo, Nup) ->
+random_id(Nlo, Nup) ->
[crypto:rand_uniform($a,$z+1) || _<- lists:duplicate(crypto:rand_uniform(Nlo,Nup+1),x) ].
hello_version_msg(Data) ->
@@ -79,12 +171,6 @@ hello_version_msg(Data) ->
next_seqnum(SeqNum) ->
(SeqNum + 1) band 16#ffffffff.
-decrypt_first_block(Bin, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
- <<EncBlock:BlockSize/binary, EncData/binary>> = Bin,
- {Ssh, <<?UINT32(PacketLen), _/binary>> = DecData} =
- decrypt(Ssh0, EncBlock),
- {Ssh, PacketLen, DecData, EncData}.
-
decrypt_blocks(Bin, Length, Ssh0) ->
<<EncBlocks:Length/binary, EncData/binary>> = Bin,
{Ssh, DecData} = decrypt(Ssh0, EncBlocks),
@@ -128,62 +214,45 @@ key_exchange_init_msg(Ssh0) ->
kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) ->
Random = ssh_bits:random(16),
- Compression = case proplists:get_value(compression, Opts, none) of
- openssh_zlib -> ["[email protected]", "none"];
- zlib -> ["zlib", "none"];
- none -> ["none", "zlib"]
- end,
- kexinit_messsage(Role, Random, Compression, HostKeyAlgs).
+ PrefAlgs =
+ case proplists:get_value(preferred_algorithms,Opts) of
+ undefined ->
+ default_algorithms();
+ Algs0 ->
+ Algs0
+ end,
+ kexinit_message(Role, Random, PrefAlgs, HostKeyAlgs).
key_init(client, Ssh, Value) ->
Ssh#ssh{c_keyinit = Value};
key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
-available_ssh_algos() ->
- Supports = crypto:supports(),
- CipherAlgos = [{aes_ctr, "aes128-ctr"}, {aes_cbc128, "aes128-cbc"}, {des3_cbc, "3des-cbc"}],
- Ciphers = [SshAlgo ||
- {CryptoAlgo, SshAlgo} <- CipherAlgos,
- lists:member(CryptoAlgo, proplists:get_value(ciphers, Supports, []))],
- HashAlgos = [{sha256, "hmac-sha2-256"}, {sha, "hmac-sha1"}],
- Hashs = [SshAlgo ||
- {CryptoAlgo, SshAlgo} <- HashAlgos,
- lists:member(CryptoAlgo, proplists:get_value(hashs, Supports, []))],
- {Ciphers, Hashs}.
-
-kexinit_messsage(client, Random, Compression, HostKeyAlgs) ->
- {CipherAlgs, HashAlgs} = available_ssh_algos(),
- #ssh_msg_kexinit{
- cookie = Random,
- kex_algorithms = ["diffie-hellman-group1-sha1"],
- server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = CipherAlgs,
- encryption_algorithms_server_to_client = CipherAlgs,
- mac_algorithms_client_to_server = HashAlgs,
- mac_algorithms_server_to_client = HashAlgs,
- compression_algorithms_client_to_server = Compression,
- compression_algorithms_server_to_client = Compression,
- languages_client_to_server = [],
- languages_server_to_client = []
- };
-kexinit_messsage(server, Random, Compression, HostKeyAlgs) ->
- {CipherAlgs, HashAlgs} = available_ssh_algos(),
+kexinit_message(_Role, Random, Algs, HostKeyAlgs) ->
#ssh_msg_kexinit{
cookie = Random,
- kex_algorithms = ["diffie-hellman-group1-sha1"],
+ kex_algorithms = to_strings( get_algs(kex,Algs) ),
server_host_key_algorithms = HostKeyAlgs,
- encryption_algorithms_client_to_server = CipherAlgs,
- encryption_algorithms_server_to_client = CipherAlgs,
- mac_algorithms_client_to_server = HashAlgs,
- mac_algorithms_server_to_client = HashAlgs,
- compression_algorithms_client_to_server = Compression,
- compression_algorithms_server_to_client = Compression,
+ encryption_algorithms_client_to_server = c2s(cipher,Algs),
+ encryption_algorithms_server_to_client = s2c(cipher,Algs),
+ mac_algorithms_client_to_server = c2s(mac,Algs),
+ mac_algorithms_server_to_client = s2c(mac,Algs),
+ compression_algorithms_client_to_server = c2s(compression,Algs),
+ compression_algorithms_server_to_client = s2c(compression,Algs),
languages_client_to_server = [],
languages_server_to_client = []
}.
+c2s(Key, Algs) -> x2y(client2server, Key, Algs).
+s2c(Key, Algs) -> x2y(server2client, Key, Algs).
+
+x2y(DirectionKey, Key, Algs) -> to_strings(proplists:get_value(DirectionKey, get_algs(Key,Algs))).
+
+get_algs(Key, Algs) -> proplists:get_value(Key, Algs, default_algorithms(Key)).
+
+to_strings(L) -> lists:map(fun erlang:atom_to_list/1, L).
+
new_keys_message(Ssh0) ->
{SshPacket, Ssh} =
ssh_packet(#ssh_msg_newkeys{}, Ssh0),
@@ -198,154 +267,411 @@ handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
Ssh0#ssh{algorithms = Algoritms});
_ ->
%% TODO: Correct code?
- throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
description = "Selection of key exchange"
" algorithm failed",
- language = "en"})
+ language = ""})
end;
handle_kexinit_msg(#ssh_msg_kexinit{} = CounterPart, #ssh_msg_kexinit{} = Own,
#ssh{role = server} = Ssh) ->
{ok, Algoritms} = select_algorithm(server, CounterPart, Own),
- {ok, Ssh#ssh{algorithms = Algoritms}}.
+ case verify_algorithm(Algoritms) of
+ true ->
+ {ok, Ssh#ssh{algorithms = Algoritms}};
+ _ ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Selection of key exchange"
+ " algorithm failed",
+ language = ""})
+ end.
%% TODO: diffie-hellman-group14-sha1 should also be supported.
%% Maybe check more things ...
-verify_algorithm(#alg{kex = 'diffie-hellman-group1-sha1'}) ->
- true;
-verify_algorithm(#alg{kex = 'diffie-hellman-group-exchange-sha1'}) ->
- true;
-verify_algorithm(_) ->
- false.
-key_exchange_first_msg('diffie-hellman-group1-sha1', Ssh0) ->
- {G, P} = dh_group1(),
- {Private, Public} = dh_gen_key(G, P, 1024),
+verify_algorithm(#alg{kex = undefined}) -> false;
+verify_algorithm(#alg{hkey = undefined}) -> false;
+verify_algorithm(#alg{send_mac = undefined}) -> false;
+verify_algorithm(#alg{recv_mac = undefined}) -> false;
+verify_algorithm(#alg{encrypt = undefined}) -> false;
+verify_algorithm(#alg{decrypt = undefined}) -> false;
+verify_algorithm(#alg{compress = undefined}) -> false;
+verify_algorithm(#alg{decompress = undefined}) -> false;
+verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex)).
+
+%%%----------------------------------------------------------------
+%%%
+%%% Key exchange initialization
+%%%
+key_exchange_first_msg(Kex, Ssh0) when Kex == 'diffie-hellman-group1-sha1' ;
+ Kex == 'diffie-hellman-group14-sha1' ->
+ {G, P} = dh_group(Kex),
+ {Public, Private} = generate_key(dh, [P,G]),
{SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_init{e = Public}, Ssh0),
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}};
-key_exchange_first_msg('diffie-hellman-group-exchange-sha1', Ssh0) ->
- Min = ?DEFAULT_DH_GROUP_MIN,
- NBits = ?DEFAULT_DH_GROUP_NBITS,
- Max = ?DEFAULT_DH_GROUP_MAX,
+key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-group-exchange-sha1' ;
+ Kex == 'diffie-hellman-group-exchange-sha256' ->
+ {Min,NBits,Max} =
+ proplists:get_value(dh_gex_limits, Opts, {?DEFAULT_DH_GROUP_MIN,
+ ?DEFAULT_DH_GROUP_NBITS,
+ ?DEFAULT_DH_GROUP_MAX}),
{SshPacket, Ssh1} =
ssh_packet(#ssh_msg_kex_dh_gex_request{min = Min,
- n = NBits, max = Max},
+ n = NBits,
+ max = Max},
Ssh0),
{ok, SshPacket,
- Ssh1#ssh{keyex_info = {Min, Max, NBits}}}.
-
-
-handle_kexdh_init(#ssh_msg_kexdh_init{e = E}, Ssh0) ->
- {G, P} = dh_group1(),
+ Ssh1#ssh{keyex_info = {Min, Max, NBits}}};
+
+key_exchange_first_msg(Kex, Ssh0) when Kex == 'ecdh-sha2-nistp256' ;
+ Kex == 'ecdh-sha2-nistp384' ;
+ Kex == 'ecdh-sha2-nistp521' ->
+ Curve = ecdh_curve(Kex),
+ {Public, Private} = generate_key(ecdh, Curve),
+ {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kex_ecdh_init{q_c=Public}, Ssh0),
+ {ok, SshPacket,
+ Ssh1#ssh{keyex_key = {{Public,Private},Curve}}}.
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-group1-sha1
+%%% diffie-hellman-group14-sha1
+%%%
+handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ %% server
+ {G, P} = dh_group(Kex),
if
1=<E, E=<(P-1) ->
- {Private, Public} = dh_gen_key(G, P, 1024),
- K = ssh_math:ipow(E, Private, P),
- Key = get_host_key(Ssh0),
- H = kex_h(Ssh0, Key, E, Public, K),
- H_SIG = sign_host_key(Ssh0, Key, H),
- {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
- f = Public,
- h_sig = H_SIG
- }, Ssh0),
-
+ {Public, Private} = generate_key(dh, [P,G]),
+ K = compute_key(dh, E, Private, [P,G]),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kexdh_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG
+ }, Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
shared_secret = K,
exchanged_hash = H,
session_id = sid(Ssh1, H)}};
+
true ->
- Error = {error,bad_e_from_peer},
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed, 'f' out of bounds",
- language = "en"},
- throw({Error, Disconnect})
+ throw({{error,bad_e_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'e' out of bounds",
+ language = ""}
+ })
end.
+handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = PeerPubHostKey,
+ f = F,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{Private, Public}, {G, P}}} = Ssh0) ->
+ %% client
+ if
+ 1=<F, F=<(P-1)->
+ K = compute_key(dh, F, Private, [P,G]),
+ H = kex_h(Ssh0, PeerPubHostKey, Public, F, K),
+
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ Error ->
+ throw({Error,
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = "en"}
+ })
+ end;
+
+ true ->
+ throw({{error,bad_f_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = ""}
+ })
+ end.
+
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-group-exchange-sha1
+%%%
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
+ n = NBits,
+ max = Max0},
+ Ssh0=#ssh{opts=Opts}) when Min0=<NBits, NBits=<Max0 ->
+ %% server
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
+ Ssh0=#ssh{opts=Opts}) ->
+ %% server
+ %%
+ %% This message was in the draft-00 of rfc4419
+ %% (https://tools.ietf.org/html/draft-ietf-secsh-dh-group-exchange-00)
+ %% In later drafts and the rfc is "is used for backward compatibility".
+ %% Unfortunatly the rfc does not specify how to treat the parameter n
+ %% if there is no group of that modulus length :(
+ %% The draft-00 however specifies that n is the "... number of bits
+ %% the subgroup should have at least".
+ %% Further, it says that "Servers and clients SHOULD support groups
+ %% with a modulus length of k bits, where 1024 <= k <= 8192."
+ %%
+ Min0 = NBits,
+ Max0 = 8192,
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {-1, -1, NBits} % flag for kex_h hash calc
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
+handle_kex_dh_gex_request(_, _) ->
+ throw({{error,bad_ssh_msg_kex_dh_gex_request},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, bad values in ssh_msg_kex_dh_gex_request",
+ language = ""}
+ }).
+
+
+adjust_gex_min_max(Min0, Max0, Opts) ->
+ case proplists:get_value(dh_gex_limits, Opts) of
+ undefined ->
+ {Min0, Max0};
+ {Min1, Max1} ->
+ Min2 = max(Min0, Min1),
+ Max2 = min(Max0, Max1),
+ if
+ Min2 =< Max2 ->
+ {Min2, Max2};
+ Max2 < Min2 ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group possible",
+ language = ""})
+ end
+ end.
+
+
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
- {Private, Public} = dh_gen_key(G,P,1024),
+ %% client
+ {Public, Private} = generate_key(dh, [P,G]),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kex_dh_gex_init{e = Public}, Ssh0),
+ ssh_packet(#ssh_msg_kex_dh_gex_init{e = Public}, Ssh0), % Pub = G^Priv mod P (def)
+
{ok, SshPacket,
Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}}}}.
+handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
+ #ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}} =
+ Ssh0) ->
+ %% server
+ if
+ 1=<E, E=<(P-1) ->
+ K = compute_key(dh, E, Private, [P,G]),
+ if
+ 1<K, K<(P-1) ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, Min, NBits, Max, P, G, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)
+ }};
+ true ->
+ throw({{error,bad_K},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'K' out of bounds",
+ language = ""}
+ })
+ end;
+ true ->
+ throw({{error,bad_e_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'e' out of bounds",
+ language = ""}
+ })
+ end.
+
+handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostKey,
+ f = F,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}} =
+ Ssh0) ->
+ %% client
+ if
+ 1=<F, F=<(P-1)->
+ K = compute_key(dh, F, Private, [P,G]),
+ if
+ 1<K, K<(P-1) ->
+ H = kex_h(Ssh0, PeerPubHostKey, Min, NBits, Max, P, G, Public, F, K),
+
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ _Error ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = ""}
+ )
+ end;
+
+ true ->
+ throw({{error,bad_K},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'K' out of bounds",
+ language = ""}
+ })
+ end;
+ true ->
+ throw({{error,bad_f_from_peer},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = ""}
+ })
+ end.
+
+%%%----------------------------------------------------------------
+%%%
+%%% diffie-hellman-ecdh-sha2-*
+%%%
+handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
+ Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
+ %% at server
+ Curve = ecdh_curve(Kex),
+ {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, Curve, MyPubHostKey, PeerPublic, MyPublic, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = MyPubHostKey,
+ q_s = MyPublic,
+ h_sig = H_SIG},
+ Ssh0),
+ {ok, SshPacket, Ssh1#ssh{keyex_key = {{MyPublic,MyPrivate},Curve},
+ shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh1, H)}}
+ catch
+ _:_ ->
+ throw({{error,invalid_peer_public_key},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Peer ECDH public key is invalid",
+ language = ""}
+ })
+ end.
+
+handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
+ q_s = PeerPublic,
+ h_sig = H_SIG},
+ #ssh{keyex_key = {{MyPublic,MyPrivate}, Curve}} = Ssh0
+ ) ->
+ %% at client
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ H = kex_h(Ssh0, Curve, PeerPubHostKey, MyPublic, PeerPublic, K),
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
+ ok ->
+ {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
+ {ok, SshPacket, Ssh#ssh{shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh, H)}};
+ Error ->
+ throw({Error,
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed",
+ language = ""}
+ })
+ end
+ catch
+ _:_ ->
+ throw({{error,invalid_peer_public_key},
+ #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Peer ECDH public key is invalid",
+ language = ""}
+ })
+ end.
+
+
+%%%----------------------------------------------------------------
handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
try install_alg(Ssh0) of
#ssh{} = Ssh ->
{ok, Ssh}
catch
- error:_Error -> %% TODO: Throw earlier ....
+ _C:_Error -> %% TODO: Throw earlier ....
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
description = "Install alg failed",
language = "en"})
end.
-
-%% %% Select algorithms
-handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
- h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) when 1=<F, F=<(P-1)->
- K = ssh_math:ipow(F, Private, P),
- H = kex_h(Ssh0, HostKey, Public, F, K),
-
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
- ok ->
- {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
- Error ->
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed",
- language = "en"},
- throw({Error, Disconnect})
- end;
-handle_kexdh_reply(#ssh_msg_kexdh_reply{}, _SSH) ->
- Error = {error,bad_f_from_peer},
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed, 'f' out of bounds",
- language = "en"},
- throw({Error, Disconnect}).
-
-
-handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = _Min,
- n = _NBits,
- max = _Max}, Ssh0) ->
- {G,P} = dh_group1(), %% TODO real imp this seems to be a hack?!
- {Private, Public} = dh_gen_key(G, P, 1024),
- {SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
- {ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}}}}.
-
-handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
- f = F,
- h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}} =
- Ssh0) ->
- K = ssh_math:ipow(F, Private, P),
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, Public, F, K),
-
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
- ok ->
- {SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
- {ok, SshPacket, Ssh#ssh{shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh, H)}};
- _Error ->
- Disconnect = #ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- description = "Key exchange failed",
- language = "en"},
- throw(Disconnect)
- end.
-
%% select session id
sid(#ssh{session_id = undefined}, H) ->
H;
@@ -359,33 +685,49 @@ get_host_key(SSH) ->
#ssh{key_cb = Mod, opts = Opts, algorithms = ALG} = SSH,
case Mod:host_key(ALG#alg.hkey, Opts) of
- {ok, #'RSAPrivateKey'{} = Key} ->
- Key;
- {ok, #'DSAPrivateKey'{} = Key} ->
- Key;
+ {ok, #'RSAPrivateKey'{} = Key} -> Key;
+ {ok, #'DSAPrivateKey'{} = Key} -> Key;
+ {ok, #'ECPrivateKey'{} = Key} -> Key;
Result ->
exit({error, {Result, unsupported_key_type}})
end.
-sign_host_key(_Ssh, #'RSAPrivateKey'{} = Private, H) ->
- Hash = sha, %% Option ?!
- _Signature = sign(H, Hash, Private);
-sign_host_key(_Ssh, #'DSAPrivateKey'{} = Private, H) ->
- Hash = sha, %% Option ?!
- _RawSignature = sign(H, Hash, Private).
+sign_host_key(_Ssh, PrivateKey, H) ->
+ sign(H, sign_host_key_sha(PrivateKey), PrivateKey).
+
+sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve,OID}}) -> sha(OID);
+sign_host_key_sha(#'RSAPrivateKey'{}) -> sha;
+sign_host_key_sha(#'DSAPrivateKey'{}) -> sha.
+
+
+extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
+ #'RSAPublicKey'{modulus = N, publicExponent = E};
+extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
+ {Y, #'Dss-Parms'{p=P, q=Q, g=G}};
+extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
+ publicKey = Q}) ->
+ {#'ECPoint'{point=Q}, {namedCurve,OID}}.
+
verify_host_key(SSH, PublicKey, Digest, Signature) ->
- case verify(Digest, sha, Signature, PublicKey) of
+ case verify(Digest, host_key_sha(PublicKey), Signature, PublicKey) of
false ->
{error, bad_signature};
true ->
known_host_key(SSH, PublicKey, public_algo(PublicKey))
end.
-public_algo(#'RSAPublicKey'{}) ->
- 'ssh-rsa';
-public_algo({_, #'Dss-Parms'{}}) ->
- 'ssh-dss'.
+
+host_key_sha(#'RSAPublicKey'{}) -> sha;
+host_key_sha({_, #'Dss-Parms'{}}) -> sha;
+host_key_sha({#'ECPoint'{},{namedCurve,OID}}) -> sha(OID).
+
+public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa';
+public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
+public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
+ Curve = public_key:oid2ssh_curvename(OID),
+ list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
+
accepted_host(Ssh, PeerName, Opts) ->
case proplists:get_value(silently_accept_hosts, Opts, false) of
@@ -418,8 +760,12 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
%% The first algorithm in each list MUST be the preferred (guessed)
%% algorithm. Each string MUST contain at least one algorithm name.
select_algorithm(Role, Client, Server) ->
- {Encrypt, Decrypt} = select_encrypt_decrypt(Role, Client, Server),
- {SendMac, RecvMac} = select_send_recv_mac(Role, Client, Server),
+ {Encrypt0, Decrypt0} = select_encrypt_decrypt(Role, Client, Server),
+ {SendMac0, RecvMac0} = select_send_recv_mac(Role, Client, Server),
+
+ {Encrypt, SendMac} = aead_gcm_simultan(Encrypt0, SendMac0),
+ {Decrypt, RecvMac} = aead_gcm_simultan(Decrypt0, RecvMac0),
+
{Compression, Decompression} =
select_compression_decompression(Role, Client, Server),
@@ -450,6 +796,38 @@ select_algorithm(Role, Client, Server) ->
s_lng = S_Lng},
{ok, Alg}.
+
+%%% It is an agreed problem with RFC 5674 that if the selection is
+%%% Cipher = AEAD_AES_x_GCM and
+%%% Mac = AEAD_AES_y_GCM (where x =/= y)
+%%% then it is undefined what length should be selected.
+%%%
+%%% If only one of the two lengths (128,256) is available, I claim that
+%%% there is no such ambiguity.
+
+%%% From https://anongit.mindrot.org/openssh.git/plain/PROTOCOL
+%%% (read Nov 20, 2015)
+%%% 1.6 transport: AES-GCM
+%%%
+%%% OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
+%%% Because of problems with the specification of the key exchange
+%%% the behaviour of OpenSSH differs from the RFC as follows:
+%%%
+%%% AES-GCM is only negotiated as the cipher algorithms
+%%% "[email protected]" or "[email protected]" and never as
+%%% an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
+%%% the exchanged MAC algorithms are ignored and there doesn't have to be
+%%% a matching MAC.
+
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('[email protected]', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan('AEAD_AES_128_GCM', _) -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan('AEAD_AES_256_GCM', _) -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_128_GCM') -> {'AEAD_AES_128_GCM', 'AEAD_AES_128_GCM'};
+aead_gcm_simultan(_, 'AEAD_AES_256_GCM') -> {'AEAD_AES_256_GCM', 'AEAD_AES_256_GCM'};
+aead_gcm_simultan(Cipher, Mac) -> {Cipher,Mac}.
+
+
select_encrypt_decrypt(client, Client, Server) ->
Encrypt =
select(Client#ssh_msg_kexinit.encryption_algorithms_client_to_server,
@@ -484,18 +862,18 @@ select_compression_decompression(client, Client, Server) ->
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion};
+ {Compression, Decompression};
select_compression_decompression(server, Client, Server) ->
- Decomprssion =
+ Decompression =
select(Client#ssh_msg_kexinit.compression_algorithms_client_to_server,
Server#ssh_msg_kexinit.compression_algorithms_client_to_server),
Compression =
select(Client#ssh_msg_kexinit.compression_algorithms_server_to_client,
Server#ssh_msg_kexinit.compression_algorithms_server_to_client),
- {Compression, Decomprssion}.
+ {Compression, Decompression}.
install_alg(SSH) ->
SSH1 = alg_final(SSH),
@@ -537,14 +915,15 @@ alg_final(SSH0) ->
{ok,SSH6} = decompress_final(SSH5),
SSH6.
-select_all(CL, SL) when length(CL) + length(SL) < 50 ->
+select_all(CL, SL) when length(CL) + length(SL) < ?MAX_NUM_ALGORITHMS ->
A = CL -- SL, %% algortihms only used by client
%% algorithms used by client and server (client pref)
lists:map(fun(ALG) -> list_to_atom(ALG) end, (CL -- A));
-select_all(_CL, _SL) ->
+select_all(CL, SL) ->
+ Err = lists:concat(["Received too many algorithms (",length(CL),"+",length(SL)," >= ",?MAX_NUM_ALGORITHMS,")."]),
throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "Too many algorithms",
- language = "en"}).
+ description = Err,
+ language = ""}).
select([], []) ->
@@ -565,58 +944,147 @@ ssh_packet(Msg, Ssh) ->
BinMsg = ssh_message:encode(Msg),
pack(BinMsg, Ssh).
-pack(Data0, #ssh{encrypt_block_size = BlockSize,
- send_sequence = SeqNum, send_mac = MacAlg,
- send_mac_key = MacKey}
- = Ssh0) when is_binary(Data0) ->
- {Ssh1, Data} = compress(Ssh0, Data0),
- PL = (BlockSize - ((4 + 1 + size(Data)) rem BlockSize)) rem BlockSize,
- PaddingLen = if PL < 4 -> PL + BlockSize;
- true -> PL
- end,
- Padding = ssh_bits:random(PaddingLen),
- PacketLen = 1 + PaddingLen + size(Data),
- PacketData = <<?UINT32(PacketLen),?BYTE(PaddingLen),
- Data/binary, Padding/binary>>,
- {Ssh2, EncPacket} = encrypt(Ssh1, PacketData),
- MAC = mac(MacAlg, MacKey, SeqNum, PacketData),
- Packet = [EncPacket, MAC],
- Ssh = Ssh2#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
- {Packet, Ssh}.
-
-unpack(EncodedSoFar, ReminingLenght, #ssh{recv_mac_size = MacSize} = Ssh0) ->
- SshLength = ReminingLenght - MacSize,
- {NoMac, Mac, Rest} = case MacSize of
- 0 ->
- <<NoMac0:SshLength/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, <<>>, Rest0};
- _ ->
- <<NoMac0:SshLength/binary,
- Mac0:MacSize/binary,
- Rest0/binary>> = EncodedSoFar,
- {NoMac0, Mac0, Rest0}
- end,
- {Ssh1, DecData, <<>>} =
- case SshLength of
- 0 ->
- {Ssh0, <<>>, <<>>};
- _ ->
- decrypt_blocks(NoMac, SshLength, Ssh0)
+pack(Data, Ssh=#ssh{}) ->
+ pack(Data, Ssh, 0).
+
+%%% Note: pack/3 is only to be called from tests that wants
+%%% to deliberetly send packets with wrong PacketLength!
+%%% Use pack/2 for all other purposes!
+pack(PlainText,
+ #ssh{send_sequence = SeqNum,
+ send_mac = MacAlg,
+ send_mac_key = MacKey,
+ encrypt = CryptoAlg} = Ssh0, PacketLenDeviationForTests) when is_binary(PlainText) ->
+
+ {Ssh1, CompressedPlainText} = compress(Ssh0, PlainText),
+ {EcryptedPacket, MAC, Ssh3} =
+ case pkt_type(CryptoAlg) of
+ common ->
+ PaddingLen = padding_length(4+1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?UINT32(PlainPacketLen),?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, EcryptedPacket0} = encrypt(Ssh1, PlainPacketData),
+ MAC0 = mac(MacAlg, MacKey, SeqNum, PlainPacketData),
+ {EcryptedPacket0, MAC0, Ssh2};
+ aead ->
+ PaddingLen = padding_length(1+size(CompressedPlainText), Ssh0),
+ Padding = ssh_bits:random(PaddingLen),
+ PlainPacketLen = 1 + PaddingLen + size(CompressedPlainText) + PacketLenDeviationForTests,
+ PlainPacketData = <<?BYTE(PaddingLen), CompressedPlainText/binary, Padding/binary>>,
+ {Ssh2, {EcryptedPacket0,MAC0}} = encrypt(Ssh1, {<<?UINT32(PlainPacketLen)>>,PlainPacketData}),
+ {<<?UINT32(PlainPacketLen),EcryptedPacket0/binary>>, MAC0, Ssh2}
end,
- {Ssh1, DecData, Rest, Mac}.
+ FinalPacket = [EcryptedPacket, MAC],
+ Ssh = Ssh3#ssh{send_sequence = (SeqNum+1) band 16#ffffffff},
+ {FinalPacket, Ssh}.
+
+
+padding_length(Size, #ssh{encrypt_block_size = BlockSize,
+ random_length_padding = RandomLengthPadding}) ->
+ PL = (BlockSize - (Size rem BlockSize)) rem BlockSize,
+ MinPaddingLen = if PL < 4 -> PL + BlockSize;
+ true -> PL
+ end,
+ PadBlockSize = max(BlockSize,4),
+ MaxExtraBlocks = (max(RandomLengthPadding,MinPaddingLen) - MinPaddingLen) div PadBlockSize,
+ ExtraPaddingLen = try crypto:rand_uniform(0,MaxExtraBlocks)*PadBlockSize
+ catch _:_ -> 0
+ end,
+ MinPaddingLen + ExtraPaddingLen.
+
+
+
+handle_packet_part(<<>>, Encrypted0, undefined, #ssh{decrypt = CryptoAlg} = Ssh0) ->
+ %% New ssh packet
+ case get_length(pkt_type(CryptoAlg), Encrypted0, Ssh0) of
+ get_more ->
+ %% too short to get the length
+ {get_more, <<>>, Encrypted0, undefined, Ssh0};
+
+ {ok, PacketLen, _, _, _} when PacketLen > ?SSH_MAX_PACKET_SIZE ->
+ %% far too long message than expected
+ {error, {exceeds_max_size,PacketLen}};
+
+ {ok, PacketLen, Decrypted, Encrypted1,
+ #ssh{recv_mac_size = MacSize} = Ssh1} ->
+ %% enough bytes so we got the length and can calculate how many
+ %% more bytes to expect for a full packet
+ TotalNeeded = (4 + PacketLen + MacSize),
+ handle_packet_part(Decrypted, Encrypted1, TotalNeeded, Ssh1)
+ end;
-msg_data(PacketData) ->
- <<Len:32, PaddingLen:8, _/binary>> = PacketData,
- DataLen = Len - PaddingLen - 1,
- <<_:32, _:8, Data:DataLen/binary,
- _:PaddingLen/binary>> = PacketData,
- Data.
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0)
+ when (size(DecryptedPfx)+size(EncryptedBuffer)) < TotalNeeded ->
+ %% need more bytes to finalize the packet
+ {get_more, DecryptedPfx, EncryptedBuffer, TotalNeeded, Ssh0};
+
+handle_packet_part(DecryptedPfx, EncryptedBuffer, TotalNeeded,
+ #ssh{recv_mac_size = MacSize,
+ decrypt = CryptoAlg} = Ssh0) ->
+ %% enough bytes to decode the packet.
+ DecryptLen = TotalNeeded - size(DecryptedPfx) - MacSize,
+ <<EncryptedSfx:DecryptLen/binary, Mac:MacSize/binary, NextPacketBytes/binary>> = EncryptedBuffer,
+ case pkt_type(CryptoAlg) of
+ common ->
+ {Ssh1, DecryptedSfx} = decrypt(Ssh0, EncryptedSfx),
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ case is_valid_mac(Mac, DecryptedPacket, Ssh1) of
+ false ->
+ {bad_mac, Ssh1};
+ true ->
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end;
+ aead ->
+ PacketLenBin = DecryptedPfx,
+ case decrypt(Ssh0, {PacketLenBin,EncryptedSfx,Mac}) of
+ {Ssh1, error} ->
+ {bad_mac, Ssh1};
+ {Ssh1, DecryptedSfx} ->
+ DecryptedPacket = <<DecryptedPfx/binary, DecryptedSfx/binary>>,
+ {Ssh, DecompressedPayload} = decompress(Ssh1, payload(DecryptedPacket)),
+ {decoded, DecompressedPayload, NextPacketBytes, Ssh}
+ end
+ end.
+
+
+get_length(common, EncryptedBuffer, #ssh{decrypt_block_size = BlockSize} = Ssh0) ->
+ case size(EncryptedBuffer) >= erlang:max(8, BlockSize) of
+ true ->
+ <<EncBlock:BlockSize/binary, EncryptedRest/binary>> = EncryptedBuffer,
+ {Ssh,
+ <<?UINT32(PacketLen),_/binary>> = Decrypted} = decrypt(Ssh0, EncBlock),
+ {ok, PacketLen, Decrypted, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end;
+get_length(aead, EncryptedBuffer, Ssh) ->
+ case size(EncryptedBuffer) >= 4 of
+ true ->
+ <<?UINT32(PacketLen), EncryptedRest/binary>> = EncryptedBuffer,
+ {ok, PacketLen, <<?UINT32(PacketLen)>>, EncryptedRest, Ssh};
+ false ->
+ get_more
+ end.
+
+pkt_type('AEAD_AES_128_GCM') -> aead;
+pkt_type('AEAD_AES_256_GCM') -> aead;
+pkt_type(_) -> common.
+
+payload(<<PacketLen:32, PaddingLen:8, PayloadAndPadding/binary>>) ->
+ PayloadLen = PacketLen - PaddingLen - 1,
+ <<Payload:PayloadLen/binary, _/binary>> = PayloadAndPadding,
+ Payload.
sign(SigData, Hash, #'DSAPrivateKey'{} = Key) ->
DerSignature = public_key:sign(SigData, Hash, Key),
#'Dss-Sig-Value'{r = R, s = S} = public_key:der_decode('Dss-Sig-Value', DerSignature),
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>>;
+sign(SigData, Hash, Key = #'ECPrivateKey'{}) ->
+ DerEncodedSign = public_key:sign(SigData, Hash, Key),
+ #'ECDSA-Sig-Value'{r=R, s=S} = public_key:der_decode('ECDSA-Sig-Value', DerEncodedSign),
+ ssh_bits:encode([R,S], [mpint,mpint]);
sign(SigData, Hash, Key) ->
public_key:sign(SigData, Hash, Key).
@@ -624,59 +1092,48 @@ verify(PlainText, Hash, Sig, {_, #'Dss-Parms'{}} = Key) ->
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> = Sig,
Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
public_key:verify(PlainText, Hash, Signature, Key);
+verify(PlainText, Hash, Sig, {#'ECPoint'{},_} = Key) ->
+ <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
+ ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> = Sig,
+ Sval = #'ECDSA-Sig-Value'{r=R, s=S},
+ DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
+ public_key:verify(PlainText, Hash, DerEncodedSig, Key);
verify(PlainText, Hash, Sig, Key) ->
public_key:verify(PlainText, Hash, Sig, Key).
-%% public key algorithms
-%%
-%% ssh-dss REQUIRED sign Raw DSS Key
-%% ssh-rsa RECOMMENDED sign Raw RSA Key
-%% x509v3-sign-rsa OPTIONAL sign X.509 certificates (RSA key)
-%% x509v3-sign-dss OPTIONAL sign X.509 certificates (DSS key)
-%% spki-sign-rsa OPTIONAL sign SPKI certificates (RSA key)
-%% spki-sign-dss OPTIONAL sign SPKI certificates (DSS key)
-%% pgp-sign-rsa OPTIONAL sign OpenPGP certificates (RSA key)
-%% pgp-sign-dss OPTIONAL sign OpenPGP certificates (DSS key)
-%%
-
-%% key exchange
-%%
-%% diffie-hellman-group1-sha1 REQUIRED
-%%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Encryption
%%
-%% chiphers
-%%
-%% 3des-cbc REQUIRED
-%% three-key 3DES in CBC mode
-%% blowfish-cbc OPTIONAL Blowfish in CBC mode
-%% twofish256-cbc OPTIONAL Twofish in CBC mode,
-%% with 256-bit key
-%% twofish-cbc OPTIONAL alias for "twofish256-cbc" (this
-%% is being retained for
-%% historical reasons)
-%% twofish192-cbc OPTIONAL Twofish with 192-bit key
-%% twofish128-cbc OPTIONAL Twofish with 128-bit key
-%% aes256-cbc OPTIONAL AES in CBC mode,
-%% with 256-bit key
-%% aes192-cbc OPTIONAL AES with 192-bit key
-%% aes128-cbc RECOMMENDED AES with 128-bit key
-%% serpent256-cbc OPTIONAL Serpent in CBC mode, with
-%% 256-bit key
-%% serpent192-cbc OPTIONAL Serpent with 192-bit key
-%% serpent128-cbc OPTIONAL Serpent with 128-bit key
-%% arcfour OPTIONAL the ARCFOUR stream cipher
-%% idea-cbc OPTIONAL IDEA in CBC mode
-%% cast128-cbc OPTIONAL CAST-128 in CBC mode
-%% none OPTIONAL no encryption; NOT RECOMMENDED
+%% Encryption
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encrypt_init(#ssh{encrypt = none} = Ssh) ->
{ok, Ssh};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
+encrypt_init(#ssh{encrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = '3des-cbc', role = client} = Ssh) ->
IV = hash(Ssh, "A", 64),
<<K1:8/binary, K2:8/binary, K3:8/binary>> = hash(Ssh, "C", 192),
@@ -702,18 +1159,46 @@ encrypt_init(#ssh{encrypt = 'aes128-cbc', role = server} = Ssh) ->
encrypt_block_size = 16,
encrypt_ctx = IV}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = client} = Ssh) ->
- IV = hash(Ssh, "A", 128),
+ IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
encrypt_init(#ssh{encrypt = 'aes128-ctr', role = server} = Ssh) ->
- IV = hash(Ssh, "B", 128),
+ IV = hash(Ssh, "B", 128),
<<K:16/binary>> = hash(Ssh, "D", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{encrypt_keys = K,
encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
+ encrypt_ctx = State}};
+encrypt_init(#ssh{encrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{encrypt_keys = K,
+ encrypt_block_size = 16,
encrypt_ctx = State}}.
encrypt_final(Ssh) ->
@@ -725,6 +1210,18 @@ encrypt_final(Ssh) ->
encrypt(#ssh{encrypt = none} = Ssh, Data) ->
{Ssh, Data};
+encrypt(#ssh{encrypt = 'AEAD_AES_128_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
+encrypt(#ssh{encrypt = 'AEAD_AES_256_GCM',
+ encrypt_keys = K,
+ encrypt_ctx = IV0} = Ssh, Data={_AAD,_Ptext}) ->
+ Enc = {_Ctext,_Ctag} = crypto:block_encrypt(aes_gcm, K, IV0, Data),
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{encrypt_ctx = IV}, Enc};
encrypt(#ssh{encrypt = '3des-cbc',
encrypt_keys = {K1,K2,K3},
encrypt_ctx = IV0} = Ssh, Data) ->
@@ -740,6 +1237,14 @@ encrypt(#ssh{encrypt = 'aes128-cbc',
encrypt(#ssh{encrypt = 'aes128-ctr',
encrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes192-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
+ {Ssh#ssh{encrypt_ctx = State}, Enc};
+encrypt(#ssh{encrypt = 'aes256-ctr',
+ encrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_encrypt(State0,Data),
{Ssh#ssh{encrypt_ctx = State}, Enc}.
@@ -749,6 +1254,30 @@ encrypt(#ssh{encrypt = 'aes128-ctr',
decrypt_init(#ssh{decrypt = none} = Ssh) ->
{ok, Ssh};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:16/binary>> = hash(Ssh, "D", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_128_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:16/binary>> = hash(Ssh, "C", 128),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 12*8),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
+decrypt_init(#ssh{decrypt = 'AEAD_AES_256_GCM', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 12*8),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = IV}};
decrypt_init(#ssh{decrypt = '3des-cbc', role = client} = Ssh) ->
{IV, KD} = {hash(Ssh, "B", 64),
hash(Ssh, "D", 192)},
@@ -780,12 +1309,40 @@ decrypt_init(#ssh{decrypt = 'aes128-ctr', role = client} = Ssh) ->
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:24/binary>> = hash(Ssh, "D", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = client} = Ssh) ->
+ IV = hash(Ssh, "B", 128),
+ <<K:32/binary>> = hash(Ssh, "D", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
decrypt_init(#ssh{decrypt = 'aes128-ctr', role = server} = Ssh) ->
IV = hash(Ssh, "A", 128),
<<K:16/binary>> = hash(Ssh, "C", 128),
State = crypto:stream_init(aes_ctr, K, IV),
{ok, Ssh#ssh{decrypt_keys = K,
decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes192-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:24/binary>> = hash(Ssh, "C", 192),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
+ decrypt_ctx = State}};
+decrypt_init(#ssh{decrypt = 'aes256-ctr', role = server} = Ssh) ->
+ IV = hash(Ssh, "A", 128),
+ <<K:32/binary>> = hash(Ssh, "C", 256),
+ State = crypto:stream_init(aes_ctr, K, IV),
+ {ok, Ssh#ssh{decrypt_keys = K,
+ decrypt_block_size = 16,
decrypt_ctx = State}}.
@@ -795,8 +1352,22 @@ decrypt_final(Ssh) ->
decrypt_ctx = undefined,
decrypt_block_size = 8}}.
+decrypt(Ssh, <<>>) ->
+ {Ssh, <<>>};
decrypt(#ssh{decrypt = none} = Ssh, Data) ->
{Ssh, Data};
+decrypt(#ssh{decrypt = 'AEAD_AES_128_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
+decrypt(#ssh{decrypt = 'AEAD_AES_256_GCM',
+ decrypt_keys = K,
+ decrypt_ctx = IV0} = Ssh, Data = {_AAD,_Ctext,_Ctag}) ->
+ Dec = crypto:block_decrypt(aes_gcm, K, IV0, Data), % Dec = PlainText | error
+ IV = next_gcm_iv(IV0),
+ {Ssh#ssh{decrypt_ctx = IV}, Dec};
decrypt(#ssh{decrypt = '3des-cbc', decrypt_keys = Keys,
decrypt_ctx = IV0} = Ssh, Data) ->
{K1, K2, K3} = Keys,
@@ -811,8 +1382,20 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
decrypt(#ssh{decrypt = 'aes128-ctr',
decrypt_ctx = State0} = Ssh, Data) ->
{State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes192-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
+ {Ssh#ssh{decrypt_ctx = State}, Enc};
+decrypt(#ssh{decrypt = 'aes256-ctr',
+ decrypt_ctx = State0} = Ssh, Data) ->
+ {State, Enc} = crypto:stream_decrypt(State0,Data),
{Ssh#ssh{decrypt_ctx = State}, Enc}.
+
+next_gcm_iv(<<Fixed:32, InvCtr:64>>) -> <<Fixed:32, (InvCtr+1):64>>.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
%%
@@ -895,49 +1478,54 @@ decompress(#ssh{decompress = '[email protected]', decompress_ctx = Context, authe
{Ssh, list_to_binary(Decompressed)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% MAC calculation
%%
-%% hmac-sha1 REQUIRED HMAC-SHA1 (digest length = key
-%% length = 20)
-%% hmac-sha1-96 RECOMMENDED first 96 bits of HMAC-SHA1 (digest
-%% length = 12, key length = 20)
-%% hmac-md5 OPTIONAL HMAC-MD5 (digest length = key
-%% length = 16)
-%% hmac-md5-96 OPTIONAL first 96 bits of HMAC-MD5 (digest
-%% length = 12, key length = 16)
-%% none OPTIONAL no MAC; NOT RECOMMENDED
+%% MAC calculation
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
send_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- KeySize =mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "E", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }};
- server ->
- KeySize = mac_key_size(SSH#ssh.send_mac),
- Key = hash(SSH, "F", KeySize),
- {ok, SSH#ssh { send_mac_key = Key }}
+ case pkt_type(SSH#ssh.send_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "E", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }};
+ server ->
+ KeySize = mac_key_size(SSH#ssh.send_mac),
+ Key = hash(SSH, "F", KeySize),
+ {ok, SSH#ssh { send_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
send_mac_final(SSH) ->
- {ok, SSH#ssh { send_mac = none, send_mac_key = undefined }}.
+ {ok, SSH#ssh {send_mac = none,
+ send_mac_key = undefined }}.
+
recv_mac_init(SSH) ->
- case SSH#ssh.role of
- client ->
- Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }};
- server ->
- Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
- {ok, SSH#ssh { recv_mac_key = Key }}
+ case pkt_type(SSH#ssh.recv_mac) of
+ common ->
+ case SSH#ssh.role of
+ client ->
+ Key = hash(SSH, "F", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }};
+ server ->
+ Key = hash(SSH, "E", mac_key_size(SSH#ssh.recv_mac)),
+ {ok, SSH#ssh { recv_mac_key = Key }}
+ end;
+ aead ->
+ %% Not applicable
+ {ok, SSH}
end.
recv_mac_final(SSH) ->
{ok, SSH#ssh { recv_mac = none, recv_mac_key = undefined }}.
-mac(none, _ , _, _) ->
+mac(none, _ , _, _) ->
<<>>;
mac('hmac-sha1', Key, SeqNum, Data) ->
crypto:hmac(sha, Key, [<<?UINT32(SeqNum)>>, Data]);
@@ -948,7 +1536,9 @@ mac('hmac-md5', Key, SeqNum, Data) ->
mac('hmac-md5-96', Key, SeqNum, Data) ->
crypto:hmac(md5, Key, [<<?UINT32(SeqNum)>>, Data], mac_digest_size('hmac-md5-96'));
mac('hmac-sha2-256', Key, SeqNum, Data) ->
- crypto:hmac(sha256, Key, [<<?UINT32(SeqNum)>>, Data]).
+ crypto:hmac(sha256, Key, [<<?UINT32(SeqNum)>>, Data]);
+mac('hmac-sha2-512', Key, SeqNum, Data) ->
+ crypto:hmac(sha512, Key, [<<?UINT32(SeqNum)>>, Data]).
%% return N hash bytes (HASH)
hash(SSH, Char, Bits) ->
@@ -956,8 +1546,20 @@ hash(SSH, Char, Bits) ->
case SSH#ssh.kex of
'diffie-hellman-group1-sha1' ->
fun(Data) -> crypto:hash(sha, Data) end;
+ 'diffie-hellman-group14-sha1' ->
+ fun(Data) -> crypto:hash(sha, Data) end;
+
'diffie-hellman-group-exchange-sha1' ->
fun(Data) -> crypto:hash(sha, Data) end;
+ 'diffie-hellman-group-exchange-sha256' ->
+ fun(Data) -> crypto:hash(sha256, Data) end;
+
+ 'ecdh-sha2-nistp256' ->
+ fun(Data) -> crypto:hash(sha256,Data) end;
+ 'ecdh-sha2-nistp384' ->
+ fun(Data) -> crypto:hash(sha384,Data) end;
+ 'ecdh-sha2-nistp521' ->
+ fun(Data) -> crypto:hash(sha512,Data) end;
_ ->
exit({bad_algorithm,SSH#ssh.kex})
end,
@@ -981,22 +1583,36 @@ hash(K, H, Ki, N, HASH) ->
hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
kex_h(SSH, Key, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), E,F,K],
+ KeyBin, E,F,K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
- crypto:hash(sha,L).
-
+ crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
+%% crypto:hash(sha,L).
+
+kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
+ L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
+ SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
+ KeyBin, Q_c, Q_s, K],
+ [string,string,binary,binary,binary,
+ mpint,mpint,mpint]),
+ crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = if Min==-1; Max==-1 ->
+ %% flag from 'ssh_msg_kex_dh_gex_request_old'
+ %% It was like this before that message was supported,
+ %% why?
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), NBits, Prime, Gen, E,F,K],
+ KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
Ts = [string,string,binary,binary,binary,
@@ -1004,16 +1620,30 @@ kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Min, NBits, Max,
+ KeyBin, Min, NBits, Max,
Prime, Gen, E,F,K], Ts)
end,
- crypto:hash(sha,L).
+ crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
+
+sha(secp256r1) -> sha256;
+sha(secp384r1) -> sha384;
+sha(secp521r1) -> sha512;
+sha('diffie-hellman-group1-sha1') -> sha;
+sha('diffie-hellman-group14-sha1') -> sha;
+sha('diffie-hellman-group-exchange-sha1') -> sha;
+sha('diffie-hellman-group-exchange-sha256') -> sha256;
+sha(?'secp256r1') -> sha(secp256r1);
+sha(?'secp384r1') -> sha(secp384r1);
+sha(?'secp521r1') -> sha(secp521r1).
+
+
mac_key_size('hmac-sha1') -> 20*8;
mac_key_size('hmac-sha1-96') -> 20*8;
mac_key_size('hmac-md5') -> 16*8;
mac_key_size('hmac-md5-96') -> 16*8;
mac_key_size('hmac-sha2-256')-> 32*8;
+mac_key_size('hmac-sha2-512')-> 512;
mac_key_size(none) -> 0.
mac_digest_size('hmac-sha1') -> 20;
@@ -1021,6 +1651,9 @@ mac_digest_size('hmac-sha1-96') -> 12;
mac_digest_size('hmac-md5') -> 20;
mac_digest_size('hmac-md5-96') -> 12;
mac_digest_size('hmac-sha2-256') -> 32;
+mac_digest_size('hmac-sha2-512') -> 64;
+mac_digest_size('AEAD_AES_128_GCM') -> 16;
+mac_digest_size('AEAD_AES_256_GCM') -> 16;
mac_digest_size(none) -> 0.
peer_name({Host, _}) ->
@@ -1032,12 +1665,91 @@ peer_name({Host, _}) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dh_group1() ->
- {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}.
+dh_group('diffie-hellman-group1-sha1') -> ?dh_group1;
+dh_group('diffie-hellman-group14-sha1') -> ?dh_group14.
-dh_gen_key(G, P, _) ->
- {Public, Private} = crypto:generate_key(dh, [P, G]),
- {crypto:bytes_to_integer(Private), crypto:bytes_to_integer(Public)}.
+%%%----------------------------------------------------------------
+generate_key(Algorithm, Args) ->
+ {Public,Private} = crypto:generate_key(Algorithm, Args),
+ {crypto:bytes_to_integer(Public), crypto:bytes_to_integer(Private)}.
+
+
+compute_key(Algorithm, OthersPublic, MyPrivate, Args) ->
+ Shared = crypto:compute_key(Algorithm, OthersPublic, MyPrivate, Args),
+ crypto:bytes_to_integer(Shared).
+
+
+ecdh_curve('ecdh-sha2-nistp256') -> secp256r1;
+ecdh_curve('ecdh-sha2-nistp384') -> secp384r1;
+ecdh_curve('ecdh-sha2-nistp521') -> secp521r1.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Utils for default_algorithms/1 and supported_algorithms/1
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
+ [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
+ [{client2server,As1--BL1},{server2client,As2--BL2}];
+supported_algorithms(Key, BlackList) ->
+ supported_algorithms(Key) -- BlackList.
+
+
+select_crypto_supported(L) ->
+ Sup = [{ec_curve,crypto_supported_curves()} | crypto:supports()],
+ [Name || {Name,CryptoRequires} <- L,
+ crypto_supported(CryptoRequires, Sup)].
+
+crypto_supported_curves() ->
+ try crypto:ec_curves()
+ catch _:_ -> []
+ end.
+
+crypto_supported(Conditions, Supported) ->
+ lists:all( fun({Tag,CryptoName}) when is_atom(CryptoName) ->
+ crypto_name_supported(Tag,CryptoName,Supported);
+ ({Tag,{Name,Len}}) when is_integer(Len) ->
+ crypto_name_supported(Tag,Name,Supported) andalso
+ len_supported(Name,Len)
+ end, Conditions).
+
+crypto_name_supported(Tag, CryptoName, Supported) ->
+ lists:member(CryptoName, proplists:get_value(Tag,Supported,[])).
+
+len_supported(Name, Len) ->
+ try
+ case Name of
+ aes_ctr ->
+ {_, <<_/binary>>} =
+ %% Test encryption
+ crypto:stream_encrypt(crypto:stream_init(Name, <<0:Len>>, <<0:128>>), <<"">>);
+ aes_gcm ->
+ {<<_/binary>>, <<_/binary>>} =
+ crypto:block_encrypt(Name,
+ _Key = <<0:Len>>,
+ _IV = <<0:12/unsigned-unit:8>>,
+ {<<"AAD">>,"PT"})
+ end
+ of
+ _ -> true
+ catch
+ _:_ -> false
+ end.
+
+
+same(Algs) -> [{client2server,Algs}, {server2client,Algs}].
+
+
+%% default_algorithms(kex) -> % Example of how to disable an algorithm
+%% supported_algorithms(kex, ['ecdh-sha2-nistp521']);
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Other utils
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
trim_tail(Str) ->
lists:reverse(trim_head(lists:reverse(Str))).
diff --git a/lib/ssh/src/ssh_transport.hrl b/lib/ssh/src/ssh_transport.hrl
index 27d3e32355..fd43326f0d 100644
--- a/lib/ssh/src/ssh_transport.hrl
+++ b/lib/ssh/src/ssh_transport.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -28,9 +29,12 @@
-define(DEFAULT_CLIENT_VERSION, {2, 0}).
-define(DEFAULT_SERVER_VERSION, {2, 0}).
--define(DEFAULT_DH_GROUP_MIN, 512).
--define(DEFAULT_DH_GROUP_NBITS, 1024).
--define(DEFAULT_DH_GROUP_MAX, 4096).
+
+-define(MAX_NUM_ALGORITHMS, 200).
+
+-define(DEFAULT_DH_GROUP_MIN, 1024).
+-define(DEFAULT_DH_GROUP_NBITS, 2048).
+-define(DEFAULT_DH_GROUP_MAX, 8192).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
@@ -108,8 +112,9 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% diffie-hellman-group1-sha1
--define(SSH_MSG_KEXDH_INIT, 30).
+%% diffie-hellman-group1-sha1 | diffie-hellman-group14-sha1
+
+-define(SSH_MSG_KEXDH_INIT, 30).
-define(SSH_MSG_KEXDH_REPLY, 31).
-record(ssh_msg_kexdh_init,
@@ -133,7 +138,7 @@
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% diffie-hellman-group-exchange-sha1
+%% diffie-hellman-group-exchange-sha1 | diffie-hellman-group-exchange-sha256
-define(SSH_MSG_KEX_DH_GEX_REQUEST_OLD, 30).
-define(SSH_MSG_KEX_DH_GEX_REQUEST, 34).
-define(SSH_MSG_KEX_DH_GEX_GROUP, 31).
@@ -170,7 +175,36 @@
h_sig
}).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% KEY ECDH messages
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% ecdh-sha2-nistp256 | ecdh-sha2-nistp384 | ecdh-sha2-nistp521
+
+-define(SSH_MSG_KEX_ECDH_INIT, 30).
+-define(SSH_MSG_KEX_ECDH_REPLY, 31).
+
+-record(ssh_msg_kex_ecdh_init,
+ {
+ q_c % string (client's ephemeral public key octet string)
+ }).
+
+-record(ssh_msg_kex_ecdh_reply,
+ {
+ public_host_key, % string (server's public host key) (k_s)
+ q_s, % string (server's ephemeral public key octet string)
+ h_sig % string (the signature on the exchange hash)
+ }).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
%% error codes
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
-define(SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT, 1).
-define(SSH_DISCONNECT_PROTOCOL_ERROR, 2).
-define(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, 3).
@@ -188,48 +222,20 @@
-define(SSH_DISCONNECT_ILLEGAL_USER_NAME, 15).
-%%%----------------------------------------------------------------------
-%%% # DH_14_xxx
-%%% Description: Oakley group 14 prime numbers and generator. Used in
-%%% diffie-hellman-group1-sha1 key exchange method.
-%%%----------------------------------------------------------------------
-%%%----------------------------------------------------------------------
-%%% # DH_14_P
-%%% Description: Prime for this group
-%%%----------------------------------------------------------------------
-
--define(DH_14_P,
- <<000,000,000,129,000,255,255,255,255,255,255,255,255,201,015,218,
- 162,033,104,194,052,196,198,098,139,128,220,028,209,041,002,078,
- 008,138,103,204,116,002,011,190,166,059,019,155,034,081,074,008,
- 121,142,052,004,221,239,149,025,179,205,058,067,027,048,043,010,
- 109,242,095,020,055,079,225,053,109,109,081,194,069,228,133,181,
- 118,098,094,126,198,244,076,066,233,166,055,237,107,011,255,092,
- 182,244,006,183,237,238,056,107,251,090,137,159,165,174,159,036,
- 017,124,075,031,230,073,040,102,081,236,230,083,129,255,255,255,
- 255,255,255,255,255>>).
-
-%%%----------------------------------------------------------------------
-%%% # DH_14_G
-%%% Description: Generator for DH_14_P.
-%%%----------------------------------------------------------------------
-
--define(DH_14_G, <<0,0,0,1,2>>).
-
-%%%----------------------------------------------------------------------
-%%% # DH_14_Q
-%%% Description: Group order (DH_14_P - 1) / 2.
-%%%----------------------------------------------------------------------
-
--define(DH_14_Q,
- <<000,000,000,128,127,255,255,255,255,255,255,255,228,135,237,081,
- 016,180,097,026,098,099,049,069,192,110,014,104,148,129,039,004,
- 069,051,230,058,001,005,223,083,029,137,205,145,040,165,004,060,
- 199,026,002,110,247,202,140,217,230,157,033,141,152,021,133,054,
- 249,047,138,027,167,240,154,182,182,168,225,034,242,066,218,187,
- 049,047,063,099,122,038,033,116,211,027,246,181,133,255,174,091,
- 122,003,091,246,247,028,053,253,173,068,207,210,215,079,146,008,
- 190,037,143,243,036,148,051,040,246,115,041,192,255,255,255,255,
- 255,255,255,255>>).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% groups
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% rfc 2489, ch 6.2
+%%% Size 1024
+-define(dh_group1,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF}).
+
+%%% rfc 3526, ch3
+%%% Size 2048
+-define(dh_group14,
+ {2, 16#FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF}).
-endif. % -ifdef(ssh_transport).
diff --git a/lib/ssh/src/ssh_userauth.hrl b/lib/ssh/src/ssh_userauth.hrl
index 7c38719d92..935999b9d1 100644
--- a/lib/ssh/src/ssh_userauth.hrl
+++ b/lib/ssh/src/ssh_userauth.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_xfer.erl b/lib/ssh/src/ssh_xfer.erl
index 2743b704f1..b8dff1c533 100644
--- a/lib/ssh/src/ssh_xfer.erl
+++ b/lib/ssh/src/ssh_xfer.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/ssh_xfer.hrl b/lib/ssh/src/ssh_xfer.hrl
index 8dc9a40f92..fe1405ccae 100644
--- a/lib/ssh/src/ssh_xfer.hrl
+++ b/lib/ssh/src/ssh_xfer.hrl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/sshc_sup.erl b/lib/ssh/src/sshc_sup.erl
index e6b4b681a4..8ee6aacfb5 100644
--- a/lib/ssh/src/sshc_sup.erl
+++ b/lib/ssh/src/sshc_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/src/sshd_sup.erl b/lib/ssh/src/sshd_sup.erl
index 60222f5172..7975b146fb 100644
--- a/lib/ssh/src/sshd_sup.erl
+++ b/lib/ssh/src/sshd_sup.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -26,8 +27,10 @@
-behaviour(supervisor).
+-include("ssh.hrl").
+
-export([start_link/1, start_child/1, stop_child/1,
- stop_child/2, system_name/1]).
+ stop_child/3, system_name/1]).
%% Supervisor callback
-export([init/1]).
@@ -40,13 +43,14 @@ start_link(Servers) ->
start_child(ServerOpts) ->
Address = proplists:get_value(address, ServerOpts),
- Port = proplists:get_value(port, ServerOpts),
- case ssh_system_sup:system_supervisor(Address, Port) of
+ Port = proplists:get_value(port, ServerOpts),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ case ssh_system_sup:system_supervisor(Address, Port, Profile) of
undefined ->
Spec = child_spec(Address, Port, ServerOpts),
case supervisor:start_child(?MODULE, Spec) of
{error, already_present} ->
- Name = id(Address, Port),
+ Name = id(Address, Port, Profile),
supervisor:delete_child(?MODULE, Name),
supervisor:start_child(?MODULE, Spec);
Reply ->
@@ -60,8 +64,8 @@ start_child(ServerOpts) ->
stop_child(Name) ->
supervisor:terminate_child(?MODULE, Name).
-stop_child(Address, Port) ->
- Name = id(Address, Port),
+stop_child(Address, Port, Profile) ->
+ Name = id(Address, Port, Profile),
stop_child(Name).
system_name(SysSup) ->
@@ -87,7 +91,8 @@ init([Servers]) ->
%%% Internal functions
%%%=========================================================================
child_spec(Address, Port, ServerOpts) ->
- Name = id(Address, Port),
+ Profile = proplists:get_value(profile, proplists:get_value(ssh_opts, ServerOpts), ?DEFAULT_PROFILE),
+ Name = id(Address, Port,Profile),
StartFunc = {ssh_system_sup, start_link, [ServerOpts]},
Restart = temporary,
Shutdown = infinity,
@@ -95,8 +100,13 @@ child_spec(Address, Port, ServerOpts) ->
Type = supervisor,
{Name, StartFunc, Restart, Shutdown, Type, Modules}.
-id(Address, Port) ->
- {server, ssh_system_sup, Address, Port}.
+id(Address, Port, Profile) ->
+ case is_list(Address) of
+ true ->
+ {server, ssh_system_sup, any, Port, Profile};
+ false ->
+ {server, ssh_system_sup, Address, Port, Profile}
+ end.
system_name([], _ ) ->
undefined;
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 740dbd0235..9cd98f069f 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -3,16 +3,17 @@
#
# Copyright Ericsson AB 2004-2013. All Rights Reserved.
#
-# The contents of this file are subject to the Erlang Public License,
-# Version 1.1, (the "License"); you may not use this file except in
-# compliance with the License. You should have received a copy of the
-# Erlang Public License along with this software. If not, it can be
-# retrieved online at http://www.erlang.org/.
+# 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
#
-# Software distributed under the License is distributed on an "AS IS"
-# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-# the License for the specific language governing rights and limitations
-# under the License.
+# 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.
#
# %CopyrightEnd%
#
@@ -31,16 +32,27 @@ VSN=$(GS_VSN)
# ----------------------------------------------------
MODULES= \
- ssh_test_lib \
+ ssh_algorithms_SUITE \
+ ssh_options_SUITE \
+ ssh_renegotiate_SUITE \
ssh_basic_SUITE \
- ssh_to_openssh_SUITE \
+ ssh_benchmark_SUITE \
+ ssh_connection_SUITE \
+ ssh_protocol_SUITE \
ssh_sftp_SUITE \
ssh_sftpd_SUITE \
ssh_sftpd_erlclient_SUITE \
- ssh_connection_SUITE \
+ ssh_sup_SUITE \
+ ssh_to_openssh_SUITE \
+ ssh_upgrade_SUITE \
+ ssh_test_lib \
+ ssh_key_cb \
+ ssh_key_cb_options \
+ ssh_trpt_test_lib \
ssh_echo_server \
ssh_peername_sockname_server \
- ssh_test_cli
+ ssh_test_cli \
+ ssh_relay
HRL_FILES_NEEDED_IN_TEST= \
$(ERL_TOP)/lib/ssh/src/ssh.hrl \
@@ -116,7 +128,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)"
$(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)"
- $(INSTALL_DATA) ssh.spec ssh.cover "$(RELSYSDIR)"
+ $(INSTALL_DATA) ssh.spec ssh_bench.spec ssh.cover "$(RELSYSDIR)"
$(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) "$(RELSYSDIR)"
chmod -R u+w "$(RELSYSDIR)"
@tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_server.erl b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
index 123b48412b..4fcb5aea69 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_server.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_client_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
index 57ea2012c1..803c8aa2ad 100644
--- a/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_encode_decode.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/property_test/ssh_eqc_subsys.erl b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
index e4b6af166f..3b395b9285 100644
--- a/lib/ssh/test/property_test/ssh_eqc_subsys.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_subsys.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/ssh.spec b/lib/ssh/test/ssh.spec
index 8de0fe44e4..0076fc275e 100644
--- a/lib/ssh/test/ssh.spec
+++ b/lib/ssh/test/ssh.spec
@@ -1,7 +1,6 @@
{suites,"../ssh_test",all}.
-{skip_cases,"../ssh_test",ssh_ssh_SUITE,
- [ssh],
- "Current implementation is timingdependent and\nhence will succeed/fail on a whim"}.
-{skip_cases,"../ssh_test",ssh_ssh_SUITE,
- [ssh_compressed],
- "Current implementation is timingdependent hence will succeed/fail on a whim"}.
+
+{skip_suites, "../ssh_test", [ssh_benchmark_SUITE],
+ "Benchmarks run separately"}.
+
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE.erl b/lib/ssh/test/ssh_algorithms_SUITE.erl
new file mode 100644
index 0000000000..f0ac92fef6
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE.erl
@@ -0,0 +1,376 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_algorithms_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(TIMEOUT, 50000).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ %% [{group,kex},{group,cipher}... etc
+ [{group,C} || C <- tags()].
+
+
+groups() ->
+ ErlAlgos = extract_algos(ssh:default_algorithms()),
+ SshcAlgos = extract_algos(ssh_test_lib:default_algorithms(sshc)),
+ SshdAlgos = extract_algos(ssh_test_lib:default_algorithms(sshd)),
+
+ DoubleAlgos =
+ [{Tag, double(Algs)} || {Tag,Algs} <- ErlAlgos,
+ length(Algs) > 1,
+ lists:member(Tag, two_way_tags())],
+ TagGroupSet =
+ [{Tag, [], group_members_for_tag(Tag,Algs,DoubleAlgos)}
+ || {Tag,Algs} <- ErlAlgos,
+ lists:member(Tag,tags())
+ ],
+
+ AlgoTcSet =
+ [{Alg, [parallel], specific_test_cases(Tag,Alg,SshcAlgos,SshdAlgos)}
+ || {Tag,Algs} <- ErlAlgos ++ DoubleAlgos,
+ Alg <- Algs],
+
+ TagGroupSet ++ AlgoTcSet.
+
+tags() -> [kex,cipher,mac,compression].
+two_way_tags() -> [cipher,mac,compression].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ct:log("os:getenv(\"HOME\") = ~p~n"
+ "init:get_argument(home) = ~p",
+ [os:getenv("HOME"), init:get_argument(home)]),
+ ct:log("~n~n"
+ "OS ssh:~n=======~n~p~n~n~n"
+ "Erl ssh:~n========~n~p~n~n~n"
+ "Installed ssh client:~n=====================~n~p~n~n~n"
+ "Installed ssh server:~n=====================~n~p~n~n~n"
+ "Misc values:~n============~n"
+ " -- Default dh group exchange parameters ({min,def,max}): ~p~n"
+ " -- dh_default_groups: ~p~n"
+ " -- Max num algorithms: ~p~n"
+ ,[os:cmd("ssh -V"),
+ ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshc),
+ ssh_test_lib:default_algorithms(sshd),
+ {?DEFAULT_DH_GROUP_MIN,?DEFAULT_DH_GROUP_NBITS,?DEFAULT_DH_GROUP_MAX},
+ public_key:dh_gex_group_sizes(),
+ ?MAX_NUM_ALGORITHMS
+ ]),
+ ct:log("all() ->~n ~p.~n~ngroups()->~n ~p.~n",[all(),groups()]),
+ catch crypto:stop(),
+ case catch crypto:start() of
+ ok ->
+ ssh:start(),
+ [{std_simple_sftp_size,25000} % Sftp transferred data size
+ | setup_pubkey(Config)];
+ _Else ->
+ {skip, "Crypto could not be started!"}
+ end.
+end_per_suite(_Config) ->
+ ssh:stop(),
+ crypto:stop().
+
+
+init_per_group(Group, Config) ->
+ case lists:member(Group, tags()) of
+ true ->
+ %% A tag group
+ Tag = Group,
+ ct:comment("==== ~p ====",[Tag]),
+ Config;
+ false ->
+ %% An algorithm group
+ Tag = proplists:get_value(name,
+ hd(?config(tc_group_path, Config))),
+ Alg = Group,
+ PA =
+ case split(Alg) of
+ [_] ->
+ [Alg];
+ [A1,A2] ->
+ [{client2server,[A1]},
+ {server2client,[A2]}]
+ end,
+ ct:log("Init tests for tag=~p alg=~p",[Tag,PA]),
+ PrefAlgs = {preferred_algorithms,[{Tag,PA}]},
+ start_std_daemon([PrefAlgs],
+ [{pref_algs,PrefAlgs} | Config])
+ end.
+
+end_per_group(_Alg, Config) ->
+ case ?config(srvr_pid,Config) of
+ Pid when is_pid(Pid) ->
+ ssh:stop_daemon(Pid),
+ ct:log("stopped ~p",[?config(srvr_addr,Config)]);
+ _ ->
+ ok
+ end.
+
+
+
+init_per_testcase(sshc_simple_exec, Config) ->
+ start_pubkey_daemon([?config(pref_algs,Config)], Config);
+
+init_per_testcase(_TC, Config) ->
+ Config.
+
+
+end_per_testcase(sshc_simple_exec, Config) ->
+ case ?config(srvr_pid,Config) of
+ Pid when is_pid(Pid) ->
+ ssh:stop_daemon(Pid),
+ ct:log("stopped ~p",[?config(srvr_addr,Config)]);
+ _ ->
+ ok
+ end;
+end_per_testcase(_TC, Config) ->
+ Config.
+
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+%% A simple sftp transfer
+simple_sftp(Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_sftp(Host, Port, Config).
+
+%%--------------------------------------------------------------------
+%% A simple exec call
+simple_exec(Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_exec(Host, Port, Config).
+
+%%--------------------------------------------------------------------
+%% Testing if no group matches
+simple_exec_groups_no_match_too_small(Config) ->
+ try simple_exec_group({400,500,600}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+simple_exec_groups_no_match_too_large(Config) ->
+ try simple_exec_group({9200,9500,9700}, Config)
+ of
+ _ -> ct:fail("Exec though no group available")
+ catch
+ error:{badmatch,{error,"No possible diffie-hellman-group-exchange group found"}} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+%% Testing all default groups
+simple_exec_groups(Config) ->
+ Sizes = interpolate( public_key:dh_gex_group_sizes() ),
+ lists:foreach(
+ fun(Sz) ->
+ ct:log("Try size ~p",[Sz]),
+ ct:comment(Sz),
+ case simple_exec_group(Sz, Config) of
+ expected -> ct:log("Size ~p ok",[Sz]);
+ _ -> ct:log("Size ~p not ok",[Sz])
+ end
+ end, Sizes),
+ ct:comment("~p",[lists:map(fun({_,I,_}) -> I;
+ (I) -> I
+ end,Sizes)]).
+
+
+interpolate([I1,I2|Is]) ->
+ OneThird = (I2-I1) div 3,
+ [I1,
+ {I1, I1 + OneThird, I2},
+ {I1, I1 + 2*OneThird, I2} | interpolate([I2|Is])];
+interpolate(Is) ->
+ Is.
+
+%%--------------------------------------------------------------------
+%% Use the ssh client of the OS to connect
+sshc_simple_exec(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(PrivDir, "known_hosts"),
+ {Host,Port} = ?config(srvr_addr, Config),
+ Cmd = lists:concat(["ssh -p ",Port,
+ " -C -o UserKnownHostsFile=",KnownHosts,
+ " ",Host," 1+1."]),
+ ct:log("~p",[Cmd]),
+ SshPort = open_port({spawn, Cmd}, [binary]),
+ receive
+ {SshPort,{data, <<"2\n">>}} ->
+ ok
+ after ?TIMEOUT ->
+ ct:fail("Did not receive answer")
+ end.
+
+%%--------------------------------------------------------------------
+%% Connect to the ssh server of the OS
+sshd_simple_exec(_Config) ->
+ ConnectionRef = ssh_test_lib:connect(22, [{silently_accept_hosts, true},
+ {user_interaction, false}]),
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId0,
+ "echo testing", infinity),
+ Data0 = {ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(Data0) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0);
+ {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}}
+ = ExitStatus0} ->
+ ct:log("0: Collected data ~p", [ExitStatus0]),
+ ssh_test_lib:receive_exec_result(Data0,
+ ConnectionRef, ChannelId0);
+ Other0 ->
+ ct:fail(Other0)
+ end,
+
+ {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId1,
+ "echo testing1", infinity),
+ Data1 = {ssh_cm, ConnectionRef, {data, ChannelId1, 0, <<"testing1\n">>}},
+ case ssh_test_lib:receive_exec_result(Data1) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1);
+ {unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId1, 0}}
+ = ExitStatus1} ->
+ ct:log("0: Collected data ~p", [ExitStatus1]),
+ ssh_test_lib:receive_exec_result(Data1,
+ ConnectionRef, ChannelId1);
+ Other1 ->
+ ct:fail(Other1)
+ end.
+
+%%%================================================================
+%%%
+%%% Lib functions
+%%%
+
+%%%----------------------------------------------------------------
+%%%
+%%% For construction of the result of all/0 and groups/0
+%%%
+group_members_for_tag(Tag, Algos, DoubleAlgos) ->
+ [{group,Alg} || Alg <- Algos++proplists:get_value(Tag,DoubleAlgos,[])].
+
+double(Algs) -> [concat(A1,A2) || A1 <- Algs,
+ A2 <- Algs,
+ A1 =/= A2].
+
+concat(A1, A2) -> list_to_atom(lists:concat([A1," + ",A2])).
+
+split(Alg) -> ssh_test_lib:to_atoms(string:tokens(atom_to_list(Alg), " + ")).
+
+specific_test_cases(Tag, Alg, SshcAlgos, SshdAlgos) ->
+ [simple_exec, simple_sftp] ++
+ case supports(Tag, Alg, SshcAlgos) of
+ true ->
+ case ssh_test_lib:ssh_type() of
+ openSSH ->
+ [sshc_simple_exec];
+ _ ->
+ []
+ end;
+ false ->
+ []
+ end ++
+ case supports(Tag, Alg, SshdAlgos) of
+ true ->
+ [sshd_simple_exec];
+ _ ->
+ []
+ end ++
+ case {Tag,Alg} of
+ {kex,_} when Alg == 'diffie-hellman-group-exchange-sha1' ;
+ Alg == 'diffie-hellman-group-exchange-sha256' ->
+ [simple_exec_groups,
+ simple_exec_groups_no_match_too_large,
+ simple_exec_groups_no_match_too_small
+ ];
+ _ ->
+ []
+ end.
+
+supports(Tag, Alg, Algos) ->
+ lists:all(fun(A) ->
+ lists:member(A, proplists:get_value(Tag, Algos,[]))
+ end,
+ split(Alg)).
+
+
+extract_algos(Spec) ->
+ [{Tag,get_atoms(List)} || {Tag,List} <- Spec].
+
+get_atoms(L) ->
+ lists:usort(
+ [ A || X <- L,
+ A <- case X of
+ {_,L1} when is_list(L1) -> L1;
+ Y when is_atom(Y) -> [Y]
+ end]).
+
+%%%----------------------------------------------------------------
+%%%
+%%% Test case related
+%%%
+start_std_daemon(Opts, Config) ->
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
+ ct:log("started ~p:~p ~p",[Host,Port,Opts]),
+ [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+
+start_pubkey_daemon(Opts, Config) ->
+ {Pid, Host, Port} = ssh_test_lib:std_daemon1(Config, Opts),
+ ct:log("started1 ~p:~p ~p",[Host,Port,Opts]),
+ [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
+
+
+setup_pubkey(Config) ->
+ DataDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
+ Config.
+
+
+simple_exec_group(I, Config) when is_integer(I) ->
+ simple_exec_group({I,I,I}, Config);
+simple_exec_group({Min,I,Max}, Config) ->
+ {Host,Port} = ?config(srvr_addr, Config),
+ ssh_test_lib:std_simple_exec(Host, Port, Config,
+ [{dh_gex_limits,{Min,I,Max}}]).
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key
index 51ab6fbd88..51ab6fbd88 100644
--- a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub
index 4dbb1305b0..4dbb1305b0 100644
--- a/lib/ssh/test/ssh_unicode_SUITE_data/ssh_host_dsa_key.pub
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_dsa_key.pub
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_algorithms_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index fa7b426545..6c4c215b3d 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -23,9 +24,52 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/inet.hrl").
+-include_lib("kernel/include/file.hrl").
%% Note: This directive should only be used in test suites.
--compile(export_all).
+%%-compile(export_all).
+
+%%% Test cases
+-export([
+ app_test/1,
+ appup_test/1,
+ cli/1,
+ close/1,
+ daemon_already_started/1,
+ daemon_opt_fd/1,
+ multi_daemon_opt_fd/1,
+ double_close/1,
+ exec/1,
+ exec_compressed/1,
+ exec_key_differs1/1,
+ exec_key_differs2/1,
+ exec_key_differs3/1,
+ exec_key_differs_fail/1,
+ idle_time/1,
+ inet6_option/1,
+ inet_option/1,
+ internal_error/1,
+ known_hosts/1,
+ misc_ssh_options/1,
+ openssh_zlib_basic_test/1,
+ packet_size_zero/1,
+ pass_phrase/1,
+ peername_sockname/1,
+ send/1,
+ shell/1,
+ shell_no_unicode/1,
+ shell_unicode_string/1,
+ ssh_info_print/1,
+ key_callback/1,
+ key_callback_options/1
+ ]).
+
+%%% Common test callbacks
+-export([suite/0, all/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2
+ ]).
-define(NEWLINE, <<"\r\n">>).
@@ -41,55 +85,51 @@ all() ->
appup_test,
{group, dsa_key},
{group, rsa_key},
+ {group, ecdsa_sha2_nistp256_key},
+ {group, ecdsa_sha2_nistp384_key},
+ {group, ecdsa_sha2_nistp521_key},
{group, dsa_pass_key},
{group, rsa_pass_key},
+ {group, host_user_key_differs},
+ {group, key_cb},
{group, internal_error},
daemon_already_started,
- server_password_option,
- server_userpassword_option,
double_close,
- ssh_connect_timeout,
- ssh_connect_arg4_timeout,
+ daemon_opt_fd,
+ multi_daemon_opt_fd,
packet_size_zero,
- ssh_daemon_minimal_remote_max_packet_size_option,
- ssh_msg_debug_fun_option_client,
- ssh_msg_debug_fun_option_server,
- id_string_no_opt_client,
- id_string_own_string_client,
- id_string_random_client,
- id_string_no_opt_server,
- id_string_own_string_server,
- id_string_random_server,
- {group, hardening_tests}
+ ssh_info_print
].
groups() ->
[{dsa_key, [], basic_tests()},
{rsa_key, [], basic_tests()},
+ {ecdsa_sha2_nistp256_key, [], basic_tests()},
+ {ecdsa_sha2_nistp384_key, [], basic_tests()},
+ {ecdsa_sha2_nistp521_key, [], basic_tests()},
+ {host_user_key_differs, [], [exec_key_differs1,
+ exec_key_differs2,
+ exec_key_differs3,
+ exec_key_differs_fail]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
- {internal_error, [], [internal_error]},
- {hardening_tests, [], [ssh_connect_nonegtimeout_connected_parallel,
- ssh_connect_nonegtimeout_connected_sequential,
- ssh_connect_negtimeout_parallel,
- ssh_connect_negtimeout_sequential,
- max_sessions_ssh_connect_parallel,
- max_sessions_ssh_connect_sequential,
- max_sessions_sftp_start_channel_parallel,
- max_sessions_sftp_start_channel_sequential
- ]}
+ {key_cb, [], [key_callback, key_callback_options]},
+ {internal_error, [], [internal_error]}
].
basic_tests() ->
[send, close, peername_sockname,
- exec, exec_compressed, shell, cli, known_hosts,
- idle_time, rekey, openssh_zlib_basic_test,
- misc_ssh_options, inet_option].
+ exec, exec_compressed,
+ shell, shell_no_unicode, shell_unicode_string,
+ cli, known_hosts,
+ idle_time, openssh_zlib_basic_test,
+ misc_ssh_options, inet_option, inet6_option].
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+ catch crypto:stop(),
case catch crypto:start() of
ok ->
Config;
@@ -100,8 +140,6 @@ end_per_suite(_Config) ->
ssh:stop(),
crypto:stop().
%%--------------------------------------------------------------------
-init_per_group(hardening_tests, Config) ->
- init_per_group(dsa_key, Config);
init_per_group(dsa_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -112,6 +150,39 @@ init_per_group(rsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_rsa(DataDir, PrivDir),
Config;
+init_per_group(ecdsa_sha2_nistp256_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp256',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp384_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp384',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("384", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp521_key, Config) ->
+ case lists:member('ecdsa-sha2-nistp521',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("521", DataDir, PrivDir),
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(rsa_pass_key, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -122,17 +193,77 @@ init_per_group(dsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa_pass_pharse(DataDir, PrivDir, "Password"),
[{pass_phrase, {dsa_pass_phrase, "Password"}}| Config];
+init_per_group(host_user_key_differs, Config) ->
+ Data = ?config(data_dir, Config),
+ Sys = filename:join(?config(priv_dir, Config), system_rsa),
+ SysUsr = filename:join(Sys, user),
+ Usr = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+ file:make_dir(Sys),
+ file:make_dir(SysUsr),
+ file:make_dir(Usr),
+ file:copy(filename:join(Data, "ssh_host_rsa_key"), filename:join(Sys, "ssh_host_rsa_key")),
+ file:copy(filename:join(Data, "ssh_host_rsa_key.pub"), filename:join(Sys, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(Data, "id_ecdsa256"), filename:join(Usr, "id_ecdsa")),
+ file:copy(filename:join(Data, "id_ecdsa256.pub"), filename:join(Usr, "id_ecdsa.pub")),
+ ssh_test_lib:setup_ecdsa_auth_keys("256", Usr, SysUsr),
+ ssh_test_lib:setup_rsa_known_host(Sys, Usr),
+ Config;
+init_per_group(key_cb, Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
init_per_group(internal_error, Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa(DataDir, PrivDir),
file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
Config;
+init_per_group(dir_options, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ %% Make unreadable dir:
+ Dir_unreadable = filename:join(PrivDir, "unread"),
+ ok = file:make_dir(Dir_unreadable),
+ {ok,F1} = file:read_file_info(Dir_unreadable),
+ ok = file:write_file_info(Dir_unreadable,
+ F1#file_info{mode = F1#file_info.mode band (bnot 8#00444)}),
+ %% Make readable file:
+ File_readable = filename:join(PrivDir, "file"),
+ ok = file:write_file(File_readable, <<>>),
+
+ %% Check:
+ case {file:read_file_info(Dir_unreadable),
+ file:read_file_info(File_readable)} of
+ {{ok, Id=#file_info{type=directory, access=Md}},
+ {ok, If=#file_info{type=regular, access=Mf}}} ->
+ AccessOK =
+ case {Md, Mf} of
+ {read, _} -> false;
+ {read_write, _} -> false;
+ {_, read} -> true;
+ {_, read_write} -> true;
+ _ -> false
+ end,
+
+ case AccessOK of
+ true ->
+ %% Save:
+ [{unreadable_dir, Dir_unreadable},
+ {readable_file, File_readable}
+ | Config];
+ false ->
+ ct:log("File#file_info : ~p~n"
+ "Dir#file_info : ~p",[If,Id]),
+ {skip, "File or dir mode settings failed"}
+ end;
+
+ NotDirFile ->
+ ct:log("{Dir,File} -> ~p",[NotDirFile]),
+ {skip, "File/Dir creation failed"}
+ end;
init_per_group(_, Config) ->
Config.
-end_per_group(hardening_tests, Config) ->
- end_per_group(dsa_key, Config);
end_per_group(dsa_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -149,6 +280,10 @@ end_per_group(rsa_pass_key, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_rsa(PrivDir),
Config;
+end_per_group(key_cb, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:clean_dsa(PrivDir),
+ Config;
end_per_group(internal_error, Config) ->
PrivDir = ?config(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -157,6 +292,33 @@ end_per_group(internal_error, Config) ->
end_per_group(_, Config) ->
Config.
%%--------------------------------------------------------------------
+init_per_testcase(TC, Config) when TC==shell_no_unicode ;
+ TC==shell_unicode_string ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ SysDir = ?config(data_dir, Config),
+ ssh:start(),
+ Sftpd = {_Pid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {user_passwords, [{"foo", "bar"}]}]),
+ ct:sleep(500),
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
+ [{silently_accept_hosts, true},
+ {user,"foo"},{password,"bar"}]),
+ ct:log("IO=~p, Shell=~p, self()=~p",[IO,Shell,self()]),
+ ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p",
+ [file:native_name_encoding(),io:getopts()]),
+ wait_for_erlang_first_line([{io,IO}, {shell,Shell}, {sftpd, Sftpd} | Config]);
+
+init_per_testcase(inet6_option, Config) ->
+ case ssh_test_lib:has_inet6_address() of
+ true ->
+ init_per_testcase('__default__', Config);
+ false ->
+ {skip,"No ipv6 interface address"}
+ end;
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -166,6 +328,15 @@ end_per_testcase(TestCase, Config) when TestCase == server_password_option;
UserDir = filename:join(?config(priv_dir, Config), nopubkey),
ssh_test_lib:del_dirs(UserDir),
end_per_testcase(Config);
+end_per_testcase(TC, Config) when TC==shell_no_unicode ;
+ TC==shell_unicode_string ->
+ case ?config(sftpd, Config) of
+ {Pid, _, _} ->
+ ssh:stop_daemon(Pid),
+ ssh:stop();
+ _ ->
+ ssh:stop()
+ end;
end_per_testcase(_TestCase, Config) ->
end_per_testcase(Config).
end_per_testcase(_Config) ->
@@ -175,21 +346,18 @@ end_per_testcase(_Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-app_test() ->
- [{doc, "App lication consistency test."}].
+%%% Application consistency test.
app_test(Config) when is_list(Config) ->
?t:app_test(ssh),
ok.
%%--------------------------------------------------------------------
-appup_test() ->
- [{doc, "Appup file consistency test."}].
+%%% Appup file consistency test.
appup_test(Config) when is_list(Config) ->
ok = ?t:appup_test(ssh).
%%--------------------------------------------------------------------
-misc_ssh_options() ->
- [{doc, "Test that we can set some misc options not tested elsewhere, "
- "some options not yet present are not decided if we should support or "
- "if they need thier own test case."}].
+%%% Test that we can set some misc options not tested elsewhere
+%%% some options not yet present are not decided if we should support or
+%%% if they need thier own test case.
misc_ssh_options(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -203,8 +371,7 @@ misc_ssh_options(Config) when is_list(Config) ->
basic_test([{client_opts, CMiscOpt1}, {server_opts, SMiscOpt1}]).
%%--------------------------------------------------------------------
-inet_option() ->
- [{doc, "Test configuring IPv4"}].
+%%% Test configuring IPv4
inet_option(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -220,8 +387,7 @@ inet_option(Config) when is_list(Config) ->
{server_opts, [{inet, inet} | ServerOpts]}]).
%%--------------------------------------------------------------------
-inet6_option() ->
- [{doc, "Test configuring IPv6"}].
+%%% Test configuring IPv6
inet6_option(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -237,8 +403,7 @@ inet6_option(Config) when is_list(Config) ->
{server_opts, [{inet, inet6} | ServerOpts]}]).
%%--------------------------------------------------------------------
-exec() ->
- [{doc, "Test api function ssh_connection:exec"}].
+%%% Test api function ssh_connection:exec
exec(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -279,37 +444,41 @@ exec(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-exec_compressed() ->
- [{doc, "Test that compression option works"}].
+%%% Test that compression option works
exec_compressed(Config) when is_list(Config) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {compression, zlib},
- {failfun, fun ssh_test_lib:failfun/2}]),
+ case ssh_test_lib:ssh_supports(zlib, compression) of
+ false ->
+ {skip, "zlib compression is not supported"};
+
+ true ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {preferred_algorithms,[{compression, [zlib]}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "1+1.", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ok;
- Other ->
- ct:fail(Other)
- end,
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
- ssh:stop_daemon(Pid).
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "1+1.", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"2\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ ssh:stop_daemon(Pid)
+ end.
%%--------------------------------------------------------------------
-idle_time() ->
- [{doc, "Idle timeout test"}].
+%%% Idle timeout test
idle_time(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -329,31 +498,9 @@ idle_time(Config) ->
{error, closed} = ssh_connection:session_channel(ConnectionRef, 1000)
end,
ssh:stop_daemon(Pid).
-%%--------------------------------------------------------------------
-rekey() ->
- [{doc, "Idle timeout test"}].
-rekey(Config) ->
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2},
- {rekey_limit, 0}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {rekey_limit, 0}]),
- receive
- after 200000 ->
- %%By this time rekeying would have been done
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid)
- end.
%%--------------------------------------------------------------------
-shell() ->
- [{doc, "Test that ssh:shell/2 works"}].
+%%% Test that ssh:shell/2 works
shell(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -369,13 +516,87 @@ shell(Config) when is_list(Config) ->
{'EXIT', _, _} ->
ct:fail(no_ssh_connection);
ErlShellStart ->
- ct:pal("Erlang shell start: ~p~n", [ErlShellStart]),
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test that we could user different types of host pubkey and user pubkey
+exec_key_differs1(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp256']).
+
+exec_key_differs2(Config) -> exec_key_differs(Config, ['ssh-dss','ecdsa-sha2-nistp256']).
+
+exec_key_differs3(Config) -> exec_key_differs(Config, ['ecdsa-sha2-nistp384','ecdsa-sha2-nistp256']).
+
+
+
+exec_key_differs(Config, UserPKAlgs) ->
+ case lists:usort(['ssh-rsa'|UserPKAlgs])
+ -- ssh_transport:supported_algorithms(public_key)
+ of
+ [] ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
+ [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,UserPKAlgs}
+ ]),
+
+
+ receive
+ {'EXIT', _, _} ->
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ do_shell(IO, Shell)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end;
+
+ UnsupportedPubKeys ->
+ {skip, io_lib:format("~p unsupported",[UnsupportedPubKeys])}
+ end.
+
+%%--------------------------------------------------------------------
+exec_key_differs_fail(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system_rsa),
+ SystemUserDir = filename:join(SystemDir, user),
+ UserDir = filename:join(?config(priv_dir, Config), user_ecdsa_256),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, SystemUserDir},
+ {preferred_algorithms,
+ [{public_key,['ssh-rsa']}]}]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ ssh_test_lib:start_shell(Port, IO, UserDir,
+ [{preferred_algorithms,[{public_key,['ssh-rsa']}]},
+ {pref_public_key_algs,['ssh-dss']}]),
+ receive
+ {'EXIT', _, _} ->
+ ok;
+ ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [ErlShellStart]),
+ ct:fail(connection_not_rejected)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-cli() ->
- [{doc, ""}].
cli(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -401,17 +622,20 @@ cli(Config) when is_list(Config) ->
{ssh_cm, ConnectionRef,
{data,0,0, <<"\r\nYou are accessing a dummy, type \"q\" to exit\r\n\n">>}} ->
ok = ssh_connection:send(ConnectionRef, ChannelId, <<"q">>)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId}} ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-daemon_already_started() ->
- [{doc, "Test that get correct error message if you try to start a daemon",
- "on an adress that already runs a daemon see also seq10667"}].
+%%% Test that get correct error message if you try to start a daemon
+%%% on an adress that already runs a daemon see also seq10667
daemon_already_started(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
UserDir = ?config(priv_dir, Config),
@@ -426,166 +650,7 @@ daemon_already_started(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-server_password_option() ->
- [{doc, "validate to server that uses the 'password' option"}].
-server_password_option(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"}]),
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
-
- Reason = "Unable to connect using the available authentication methods",
-
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "foo"},
- {user_interaction, false},
- {user_dir, UserDir}]),
-
- ct:pal("Test of wrong password: Error msg: ~p ~n", [Reason]),
-
- ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-server_userpassword_option() ->
- [{doc, "validate to server that uses the 'password' option"}].
-server_userpassword_option(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, PrivDir},
- {user_passwords, [{"vego", "morot"}]}]),
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- ssh:close(ConnectionRef),
-
- Reason = "Unable to connect using the available authentication methods",
-
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- {error, Reason} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "vego"},
- {password, "foo"},
- {user_interaction, false},
- {user_dir, UserDir}]),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-ssh_msg_debug_fun_option_client() ->
- [{doc, "validate client that uses the 'ssh_msg_debug_fun' option"}].
-ssh_msg_debug_fun_option_client(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"},
- {failfun, fun ssh_test_lib:failfun/2}]),
- Parent = self(),
- DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
-
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_dir, UserDir},
- {user_interaction, false},
- {ssh_msg_debug_fun,DbgFun}]),
- %% Beware, implementation knowledge:
- gen_fsm:send_all_state_event(ConnectionRef,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
- receive
- {msg_dbg,X={ConnectionRef,false,<<"Hello">>,<<>>}} ->
- ct:log("Got expected dbg msg ~p",[X]),
- ssh:stop_daemon(Pid);
- {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
- ct:log("Got dbg msg but bad ConnectionRef (~p expected) ~p",[ConnectionRef,X]),
- ssh:stop_daemon(Pid),
- {fail, "Bad ConnectionRef received"};
- {msg_dbg,X} ->
- ct:log("Got bad dbg msg ~p",[X]),
- ssh:stop_daemon(Pid),
- {fail,"Bad msg received"}
- after 1000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout}
- end.
-
-%%--------------------------------------------------------------------
-ssh_msg_debug_fun_option_server() ->
- [{doc, "validate client that uses the 'ssh_msg_debug_fun' option"}].
-ssh_msg_debug_fun_option_server(Config) ->
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- SysDir = ?config(data_dir, Config),
-
- Parent = self(),
- DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
- ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, UserDir},
- {password, "morot"},
- {failfun, fun ssh_test_lib:failfun/2},
- {connectfun, ConnFun},
- {ssh_msg_debug_fun, DbgFun}]),
- _ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_dir, UserDir},
- {user_interaction, false}]),
- receive
- {connection_pid,Server} ->
- %% Beware, implementation knowledge:
- gen_fsm:send_all_state_event(Server,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
- receive
- {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
- ct:log("Got expected dbg msg ~p",[X]),
- ssh:stop_daemon(Pid);
- {msg_dbg,X} ->
- ct:log("Got bad dbg msg ~p",[X]),
- ssh:stop_daemon(Pid),
- {fail,"Bad msg received"}
- after 3000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout2}
- end
- after 3000 ->
- ssh:stop_daemon(Pid),
- {fail,timeout1}
- end.
-
-%%--------------------------------------------------------------------
-known_hosts() ->
- [{doc, "check that known_hosts is updated correctly"}].
+%%% check that known_hosts is updated correctly
known_hosts(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -611,8 +676,7 @@ known_hosts(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-pass_phrase() ->
- [{doc, "Test that we can use keyes protected by pass phrases"}].
+%%% Test that we can use keyes protected by pass phrases
pass_phrase(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -631,27 +695,75 @@ pass_phrase(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+%%% Test that we can use key callback
+key_callback(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, ssh_key_cb}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% Test that we can use key callback with callback options
+key_callback_options(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ NoPubKeyDir = filename:join(UserDir, "nopubkey"),
+ file:make_dir(NoPubKeyDir),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
-internal_error() ->
- [{doc,"Test that client does not hang if disconnects due to internal error"}].
+ {ok, PrivKey} = file:read_file(filename:join(UserDir, "id_dsa")),
+
+ ConnectOpts = [{silently_accept_hosts, true},
+ {user_dir, NoPubKeyDir},
+ {user_interaction, false},
+ {key_cb, {ssh_key_cb_options, [{priv_key, PrivKey}]}}],
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, ConnectOpts),
+
+ {ok, _ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% Test that client does not hang if disconnects due to internal error
internal_error(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
{error, Error} =
- ssh:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false}]),
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
check_error(Error),
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-send() ->
- [{doc, "Test ssh_connection:send/3"}].
+%%% Test ssh_connection:send/3
send(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -671,8 +783,7 @@ send(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-peername_sockname() ->
- [{doc, "Test ssh:connection_info([peername, sockname])"}].
+%%% Test ssh:connection_info([peername, sockname])
peername_sockname(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -694,13 +805,13 @@ peername_sockname(Config) when is_list(Config) ->
ssh:connection_info(ConnectionRef, [peer]),
[{sockname, {HostSockClient,PortSockClient} = ClientSock}] =
ssh:connection_info(ConnectionRef, [sockname]),
- ct:pal("Client: ~p ~p", [ClientPeer, ClientSock]),
+ ct:log("Client: ~p ~p", [ClientPeer, ClientSock]),
receive
{ssh_cm, ConnectionRef, {data, ChannelId, _, Response}} ->
{PeerNameSrv,SockNameSrv} = binary_to_term(Response),
{HostPeerSrv,PortPeerSrv} = PeerNameSrv,
{HostSockSrv,PortSockSrv} = SockNameSrv,
- ct:pal("Server: ~p ~p", [PeerNameSrv, SockNameSrv]),
+ ct:log("Server: ~p ~p", [PeerNameSrv, SockNameSrv]),
host_equal(HostPeerSrv, HostSockClient),
PortPeerSrv = PortSockClient,
host_equal(HostSockSrv, HostPeerClient),
@@ -708,7 +819,7 @@ peername_sockname(Config) when is_list(Config) ->
host_equal(HostSockSrv, Host),
PortSockSrv = Port
after 10000 ->
- throw(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
host_equal(H1, H2) ->
@@ -722,8 +833,7 @@ ips(Name) when is_list(Name) ->
%%--------------------------------------------------------------------
-close() ->
- [{doc, "Client receives close when server closes"}].
+%%% Client receives close when server closes
close(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -743,12 +853,11 @@ close(Config) when is_list(Config) ->
{ssh_cm, Client,{closed, ChannelId}} ->
ok
after 5000 ->
- ct:fail(timeout)
+ ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
-double_close() ->
- [{doc, "Simulate that we try to close an already closed connection"}].
+%%% Simulate that we try to close an already closed connection
double_close(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -769,90 +878,66 @@ double_close(Config) when is_list(Config) ->
ok = ssh:close(CM).
%%--------------------------------------------------------------------
-ssh_connect_timeout() ->
- [{doc, "Test connect_timeout option in ssh:connect/4"}].
-ssh_connect_timeout(_Config) ->
- ConnTimeout = 2000,
- {error,{faked_transport,connect,TimeoutToTransport}} =
- ssh:connect("localhost", 12345,
- [{transport,{tcp,?MODULE,tcp_closed}},
- {connect_timeout,ConnTimeout}],
- 1000),
- case TimeoutToTransport of
- ConnTimeout -> ok;
- Other ->
- ct:log("connect_timeout is ~p but transport received ~p",[ConnTimeout,Other]),
- {fail,"ssh:connect/4 wrong connect_timeout received in transport"}
- end.
+daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ {ok,S1} = gen_tcp:listen(0,[]),
+ {ok,Fd1} = prim_inet:getfd(S1),
+
+ {ok,Pid1} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd1},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
-%% Help for the test above
-connect(_Host, _Port, _Opts, Timeout) ->
- {error, {faked_transport,connect,Timeout}}.
+ {ok,{_Host1,Port1}} = inet:sockname(S1),
+ {ok, C1} = ssh:connect("localhost", Port1, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ exit(C1, {shutdown, normal}),
+ ssh:stop_daemon(Pid1),
+ gen_tcp:close(S1).
%%--------------------------------------------------------------------
-ssh_connect_arg4_timeout() ->
- [{doc, "Test fourth argument in ssh:connect/4"}].
-ssh_connect_arg4_timeout(_Config) ->
- Timeout = 1000,
- Parent = self(),
- %% start the server
- Server = spawn(fun() ->
- {ok,Sl} = gen_tcp:listen(0,[]),
- {ok,{_,Port}} = inet:sockname(Sl),
- Parent ! {port,self(),Port},
- Rsa = gen_tcp:accept(Sl),
- ct:log("Server gen_tcp:accept got ~p",[Rsa]),
- receive after 2*Timeout -> ok end %% let client timeout first
- end),
-
- %% Get listening port
- Port = receive
- {port,Server,ServerPort} -> ServerPort
- end,
-
- %% try to connect with a timeout, but "supervise" it
- Client = spawn(fun() ->
- T0 = now(),
- Rc = ssh:connect("localhost",Port,[],Timeout),
- ct:log("Client ssh:connect got ~p",[Rc]),
- Parent ! {done,self(),Rc,T0}
- end),
-
- %% Wait for client reaction on the connection try:
- receive
- {done, Client, {error,timeout}, T0} ->
- Msp = ms_passed(T0, now()),
- exit(Server,hasta_la_vista___baby),
- Low = 0.9*Timeout,
- High = 1.1*Timeout,
- ct:log("Timeout limits: ~.4f - ~.4f ms, timeout "
- "was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]),
- %%ct:log("Timeout limits: ~p--~p, my timeout was ~p, expected ~p",[Low,High,Msp0,Timeout]),
- if
- Low<Msp, Msp<High -> ok;
- true -> {fail, "timeout not within limits"}
- end;
+multi_daemon_opt_fd(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
- {done, Client, {error,Other}, _T0} ->
- ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]),
- {fail, "Unexpected error message"};
-
- {done, Client, {ok,_Ref}, _T0} ->
- {fail,"ssh-connected ???"}
- after
- 5000 ->
- exit(Server,hasta_la_vista___baby),
- exit(Client,hasta_la_vista___baby),
- {fail, "Didn't timeout"}
- end.
+ Test =
+ fun() ->
+ {ok,S} = gen_tcp:listen(0,[]),
+ {ok,Fd} = prim_inet:getfd(S),
-%% Help function
-%% N2-N1
-ms_passed(N1={_,_,M1}, N2={_,_,M2}) ->
- {0,{0,Min,Sec}} = calendar:time_difference(calendar:now_to_local_time(N1),
- calendar:now_to_local_time(N2)),
- 1000 * (Min*60 + Sec + (M2-M1)/1000000).
+ {ok,Pid} = ssh:daemon(0, [{system_dir, SystemDir},
+ {fd,Fd},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,{_Host,Port}} = inet:sockname(S),
+ {ok, C} = ssh:connect("localhost", Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false}]),
+ {S,Pid,C}
+ end,
+
+ Tests = [Test(),Test(),Test(),Test(),Test(),Test()],
+
+ [begin
+ gen_tcp:close(S),
+ ssh:stop_daemon(Pid),
+ exit(C, {shutdown, normal})
+ end || {S,Pid,C} <- Tests].
%%--------------------------------------------------------------------
packet_size_zero(Config) ->
@@ -879,317 +964,134 @@ packet_size_zero(Config) ->
receive
{ssh_cm,Conn,{data,Chan,_Type,_Msg1}} = M ->
- ct:pal("Got ~p",[M]),
+ ct:log("Got ~p",[M]),
ct:fail(doesnt_obey_max_packet_size_0)
after 5000 ->
ok
end.
%%--------------------------------------------------------------------
-ssh_daemon_minimal_remote_max_packet_size_option(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
-
- {Server, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {user_passwords, [{"vego", "morot"}]},
- {failfun, fun ssh_test_lib:failfun/2},
- {minimal_remote_max_packet_size, 14}]),
- Conn =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {user, "vego"},
- {password, "morot"}]),
-
- %% Try the limits of the minimal_remote_max_packet_size:
- {ok, _ChannelId} = ssh_connection:session_channel(Conn, 100, 14, infinity),
- {open_error,_,"Maximum packet size below 14 not supported",_} =
- ssh_connection:session_channel(Conn, 100, 13, infinity),
-
- ssh:close(Conn),
- ssh:stop_daemon(Server).
-
-%%--------------------------------------------------------------------
-id_string_no_opt_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, []),
- receive
- {id,Server,"SSH-2.0-Erlang/"++Vsn} ->
- true = expected_ssh_vsn(Vsn);
- {id,Server,Other} ->
- ct:fail("Unexpected id: ~s.",[Other])
- end.
-
-%%--------------------------------------------------------------------
-id_string_own_string_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, [{id_string,"Pelle"}]),
- receive
- {id,Server,"SSH-2.0-Pelle\r\n"} ->
- ok;
- {id,Server,Other} ->
- ct:fail("Unexpected id: ~s.",[Other])
- end.
-
+shell_no_unicode(Config) ->
+ new_do_shell(?config(io,Config),
+ [new_prompt,
+ {type,"io:format(\"hej ~p~n\",[42])."},
+ {expect,"hej 42"}
+ ]).
+
%%--------------------------------------------------------------------
-id_string_random_client(Config) ->
- {Server, Host, Port} = fake_daemon(Config),
- {error,_} = ssh:connect(Host, Port, [{id_string,random}]),
- receive
- {id,Server,Id="SSH-2.0-Erlang"++_} ->
- ct:fail("Unexpected id: ~s.",[Id]);
- {id,Server,Rnd="SSH-2.0-"++_} ->
- ct:log("Got ~s.",[Rnd]);
- {id,Server,Id} ->
- ct:fail("Unexpected id: ~s.",[Id])
- end.
-
-%%--------------------------------------------------------------------
-id_string_no_opt_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, []),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-Erlang/"++Vsn} = gen_tcp:recv(S1, 0, 2000),
- true = expected_ssh_vsn(Vsn).
-
-%%--------------------------------------------------------------------
-id_string_own_string_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, [{id_string,"Olle"}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-Olle\r\n"} = gen_tcp:recv(S1, 0, 2000).
+shell_unicode_string(Config) ->
+ new_do_shell(?config(io,Config),
+ [new_prompt,
+ {type,"io:format(\"こにちわ~ts~n\",[\"四二\"])."},
+ {expect,"こにちわ四二"},
+ {expect,"ok"}
+ ]).
%%--------------------------------------------------------------------
-id_string_random_server(Config) ->
- {_Server, Host, Port} = std_daemon(Config, [{id_string,random}]),
- {ok,S1}=gen_tcp:connect(Host,Port,[{active,false}]),
- {ok,"SSH-2.0-"++Rnd} = gen_tcp:recv(S1, 0, 2000),
- case Rnd of
- "Erlang"++_ -> ct:log("Id=~p",[Rnd]),
- {fail,got_default_id};
- "Olle\r\n" -> {fail,got_previous_tests_value};
- _ -> ct:log("Got ~s.",[Rnd])
- end.
+%%% Test basic connection with openssh_zlib
+openssh_zlib_basic_test(Config) ->
+ case ssh_test_lib:ssh_supports(['[email protected]',none], compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
-%%--------------------------------------------------------------------
-ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true).
-ssh_connect_negtimeout_sequential(Config) -> ssh_connect_negtimeout(Config,false).
-
-ssh_connect_negtimeout(Config, Parallel) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- NegTimeOut = 2000, % ms
- ct:log("Parallel: ~p",[Parallel]),
+ true ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
- {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {parallel_login, Parallel},
- {negotiation_timeout, NegTimeOut},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- {ok,Socket} = gen_tcp:connect(Host, Port, []),
- ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
- receive after round(1.2 * NegTimeOut) -> ok end,
-
- case inet:sockname(Socket) of
- {ok,_} -> ct:fail("Socket not closed");
- {error,_} -> ok
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {preferred_algorithms,[{compression, ['[email protected]']}]},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {preferred_algorithms,[{compression, ['[email protected]',
+ none]}]}
+ ]),
+ ok = ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
end.
%%--------------------------------------------------------------------
-ssh_connect_nonegtimeout_connected_parallel() ->
- [{doc, "Test that ssh connection does not timeout if the connection is established (parallel)"}].
-ssh_connect_nonegtimeout_connected_parallel(Config) ->
- ssh_connect_nonegtimeout_connected(Config, true).
-
-ssh_connect_nonegtimeout_connected_sequential() ->
- [{doc, "Test that ssh connection does not timeout if the connection is established (non-parallel)"}].
-ssh_connect_nonegtimeout_connected_sequential(Config) ->
- ssh_connect_nonegtimeout_connected(Config, false).
-
-
-ssh_connect_nonegtimeout_connected(Config, Parallel) ->
- process_flag(trap_exit, true),
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- NegTimeOut = 20000, % ms
- ct:log("Parallel: ~p",[Parallel]),
-
- {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
- {parallel_login, Parallel},
- {negotiation_timeout, NegTimeOut},
- {failfun, fun ssh_test_lib:failfun/2}]),
- ct:pal("~p Listen ~p:~p",[_Pid,_Host,Port]),
- ct:sleep(500),
-
- IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
- receive
- Error = {'EXIT', _, _} ->
- ct:pal("~p",[Error]),
- ct:fail(no_ssh_connection);
- ErlShellStart ->
- ct:pal("---Erlang shell start: ~p~n", [ErlShellStart]),
- one_shell_op(IO, NegTimeOut),
- one_shell_op(IO, NegTimeOut),
- ct:pal("And now sleeping 1.2*NegTimeOut (~p ms)...", [round(1.2 * NegTimeOut)]),
- receive after round(1.2 * NegTimeOut) -> ok end,
- one_shell_op(IO, NegTimeOut)
- end,
- exit(Shell, kill).
-
+ssh_info_print(Config) ->
+ %% Just check that ssh_print:info() crashes
+ PrivDir = ?config(priv_dir, Config),
+ PrintFile = filename:join(PrivDir,info),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
-one_shell_op(IO, TimeOut) ->
- ct:pal("One shell op: Waiting for prompter"),
+ Parent = self(),
+ UnexpFun = fun(Msg,_Peer) ->
+ Parent ! {unexpected,Msg,self()},
+ skip
+ end,
+ ConnFun = fun(_,_,_) -> Parent ! {connect,self()} end,
+
+ {DaemonRef, Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {unexpectedfun, UnexpFun},
+ {connectfun, ConnFun},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ClientConnRef1 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {unexpectedfun, UnexpFun},
+ {user_interaction, false}]),
+ ClientConnRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {unexpectedfun, UnexpFun},
+ {user_interaction, false}]),
receive
- ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
- after TimeOut -> ct:fail("Timeout waiting for promter")
+ {connect,DaemonConnRef} ->
+ ct:log("DaemonRef=~p, DaemonConnRef=~p, ClientConnRefs=~p",[DaemonRef, DaemonConnRef,
+ [ClientConnRef1,ClientConnRef2]
+ ])
+ after 2000 ->
+ ok
end,
- IO ! {input, self(), "2*3*7.\r\n"},
- receive
- Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
- after TimeOut -> ct:fail("Timeout waiting for echo")
- end,
+ {ok,D} = file:open(PrintFile, write),
+ ssh_info:print(D),
+ ok = file:close(D),
- receive
- ?NEWLINE -> ct:log("NEWLINE received", [])
- after TimeOut ->
- receive Any1 -> ct:log("Bad NEWLINE: ~p",[Any1])
- after 0 -> ct:fail("Timeout waiting for NEWLINE")
- end
- end,
+ {ok,Bin} = file:read_file(PrintFile),
+ ct:log("~s",[Bin]),
receive
- Result0 -> ct:log("Result: ~p~n", [Result0])
- after TimeOut -> ct:fail("Timeout waiting for result")
- end.
-
-%%--------------------------------------------------------------------
-
-openssh_zlib_basic_test() ->
- [{doc, "Test basic connection with openssh_zlib"}].
-openssh_zlib_basic_test(Config) ->
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
- ConnectionRef =
- ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
- {user_dir, UserDir},
- {user_interaction, false},
- {compression, openssh_zlib}]),
- ok = ssh:close(ConnectionRef),
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-
-max_sessions_ssh_connect_parallel(Config) ->
- max_sessions(Config, true, connect_fun(ssh__connect,Config)).
-max_sessions_ssh_connect_sequential(Config) ->
- max_sessions(Config, false, connect_fun(ssh__connect,Config)).
-
-max_sessions_sftp_start_channel_parallel(Config) ->
- max_sessions(Config, true, connect_fun(ssh_sftp__start_channel, Config)).
-max_sessions_sftp_start_channel_sequential(Config) ->
- max_sessions(Config, false, connect_fun(ssh_sftp__start_channel, Config)).
-
-
-%%%---- helpers:
-connect_fun(ssh__connect, Config) ->
- fun(Host,Port) ->
- ssh_test_lib:connect(Host, Port,
- [{silently_accept_hosts, true},
- {user_dir, ?config(priv_dir,Config)},
- {user_interaction, false},
- {user, "carni"},
- {password, "meat"}
- ])
- %% ssh_test_lib returns R when ssh:connect returns {ok,R}
- end;
-connect_fun(ssh_sftp__start_channel, _Config) ->
- fun(Host,Port) ->
- {ok,_Pid,ConnRef} =
- ssh_sftp:start_channel(Host, Port,
- [{silently_accept_hosts, true},
- {user, "carni"},
- {password, "meat"}
- ]),
- ConnRef
+ {unexpected, Msg, Pid} ->
+ ct:log("~p got unexpected msg ~p",[Pid,Msg]),
+ ct:log("process_info(~p) = ~n~p",[Pid,process_info(Pid)]),
+ ok = ssh:close(ClientConnRef1),
+ ok = ssh:close(ClientConnRef2),
+ ok = ssh:stop_daemon(DaemonRef),
+ {fail,"unexpected msg"}
+ after 1000 ->
+ ok = ssh:close(ClientConnRef1),
+ ok = ssh:close(ClientConnRef2),
+ ok = ssh:stop_daemon(DaemonRef)
end.
-max_sessions(Config, ParallelLogin, Connect0) when is_function(Connect0,2) ->
- Connect = fun(Host,Port) ->
- R = Connect0(Host,Port),
- ct:pal("Connect(~p,~p) -> ~p",[Host,Port,R]),
- R
- end,
- SystemDir = filename:join(?config(priv_dir, Config), system),
- UserDir = ?config(priv_dir, Config),
- MaxSessions = 5,
- {Pid, Host, Port} = ssh_test_lib:daemon([
- {system_dir, SystemDir},
- {user_dir, UserDir},
- {user_passwords, [{"carni", "meat"}]},
- {parallel_login, ParallelLogin},
- {max_sessions, MaxSessions}
- ]),
- ct:pal("~p Listen ~p:~p for max ~p sessions",[Pid,Host,Port,MaxSessions]),
- try [Connect(Host,Port) || _ <- lists:seq(1,MaxSessions)]
- of
- Connections ->
- %% Step 1 ok: could set up max_sessions connections
- ct:log("Connections up: ~p",[Connections]),
- [_|_] = Connections,
-
- %% Now try one more than alowed:
- ct:pal("Info Report might come here...",[]),
- try Connect(Host,Port)
- of
- _ConnectionRef1 ->
- ssh:stop_daemon(Pid),
- {fail,"Too many connections accepted"}
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- %% Step 2 ok: could not set up max_sessions+1 connections
- %% This is expected
- %% Now stop one connection and try to open one more
- ok = ssh:close(hd(Connections)),
- try Connect(Host,Port)
- of
- _ConnectionRef1 ->
- %% Step 3 ok: could set up one more connection after killing one
- %% Thats good.
- ssh:stop_daemon(Pid),
- ok
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- %% Bad indeed. Could not set up one more connection even after killing
- %% one existing. Very bad.
- ssh:stop_daemon(Pid),
- {fail,"Does not decrease # active sessions"}
- end
- end
- catch
- error:{badmatch,{error,"Connection closed"}} ->
- ssh:stop_daemon(Pid),
- {fail,"Too few connections accepted"}
- end.
-
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
-
%% Due to timing the error message may or may not be delivered to
%% the "tcp-application" before the socket closed message is recived
check_error("Invalid state") ->
ok;
check_error("Connection closed") ->
ok;
+check_error("Selection of key exchange algorithm failed") ->
+ ok;
check_error(Error) ->
ct:fail(Error).
@@ -1205,28 +1107,38 @@ basic_test(Config) ->
do_shell(IO, Shell) ->
receive
ErlPrompt0 ->
- ct:pal("Erlang prompt: ~p~n", [ErlPrompt0])
+ ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
end,
IO ! {input, self(), "1+1.\r\n"},
receive
Echo0 ->
- ct:pal("Echo: ~p ~n", [Echo0])
+ ct:log("Echo: ~p ~n", [Echo0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
Result0 = <<"2">> ->
- ct:pal("Result: ~p~n", [Result0])
+ ct:log("Result: ~p~n", [Result0])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
?NEWLINE ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
ErlPrompt1 ->
- ct:pal("Erlang prompt: ~p~n", [ErlPrompt1])
+ ct:log("Erlang prompt: ~p~n", [ErlPrompt1])
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
exit(Shell, kill).
%%Does not seem to work in the testserver!
@@ -1237,7 +1149,7 @@ do_shell(IO, Shell) ->
%% end,
%% receive
%% Echo1 ->
- %% ct:pal("Echo: ~p ~n", [Echo1])
+ %% ct:log("Echo: ~p ~n", [Echo1])
%% end,
%% receive
%% ?NEWLINE ->
@@ -1245,7 +1157,7 @@ do_shell(IO, Shell) ->
%% end,
%% receive
%% Result1 ->
- %% ct:pal("Result: ~p~n", [Result1])
+ %% ct:log("Result: ~p~n", [Result1])
%% end,
%% receive
%% {'EXIT', Shell, killed} ->
@@ -1253,44 +1165,90 @@ do_shell(IO, Shell) ->
%% end.
-std_daemon(Config, ExtraOpts) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
- file:make_dir(UserDir),
- {_Server, _Host, _Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {user_dir, UserDir},
- {failfun, fun ssh_test_lib:failfun/2} | ExtraOpts]).
-
-expected_ssh_vsn(Str) ->
- try
- {ok,L} = application:get_all_key(ssh),
- proplists:get_value(vsn,L,"")++"\r\n"
- of
- Str -> true;
- "\r\n" -> true;
- _ -> false
- catch
- _:_ -> true %% ssh not started so we dont't know
+%%--------------------------------------------------------------------
+wait_for_erlang_first_line(Config) ->
+ receive
+ {'EXIT', _, _} ->
+ {fail,no_ssh_connection};
+ <<"Eshell ",_/binary>> = _ErlShellStart ->
+ ct:log("Erlang shell start: ~p~n", [_ErlShellStart]),
+ Config;
+ Other ->
+ ct:log("Unexpected answer from ssh server: ~p",[Other]),
+ {fail,unexpected_answer}
+ after 10000 ->
+ ct:log("No answer from ssh-server"),
+ {fail,timeout}
end.
-
-
-fake_daemon(_Config) ->
- Parent = self(),
- %% start the server
- Server = spawn(fun() ->
- {ok,Sl} = gen_tcp:listen(0,[]),
- {ok,{Host,Port}} = inet:sockname(Sl),
- Parent ! {sockname,self(),Host,Port},
- Rsa = gen_tcp:accept(Sl),
- ct:log("Server gen_tcp:accept got ~p",[Rsa]),
- {ok,S} = Rsa,
- receive
- {tcp, S, Id} -> Parent ! {id,self(),Id}
- end
- end),
- %% Get listening host and port
+
+
+
+new_do_shell(IO, List) -> new_do_shell(IO, 0, List).
+
+new_do_shell(IO, N, [new_prompt|More]) ->
+ new_do_shell(IO, N+1, More);
+
+new_do_shell(IO, N, Ops=[{Order,Arg}|More]) ->
+ Pfx = prompt_prefix(),
+ PfxSize = size(Pfx),
receive
- {sockname,Server,ServerHost,ServerPort} -> {Server, ServerHost, ServerPort}
+ _X = <<"\r\n">> ->
+ ct:log("Skip newline ~p",[_X]),
+ new_do_shell(IO, N, Ops);
+
+ <<Pfx:PfxSize/binary,P1,"> ">> when (P1-$0)==N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ <<Pfx:PfxSize/binary,P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ <<Pfx:PfxSize/binary,P1,P2,P3,"> ">> when (P1-$0)*100 + (P2-$0)*10 + (P3-$0) == N ->
+ new_do_shell_prompt(IO, N, Order, Arg, More);
+
+ Err when element(1,Err)==error ->
+ ct:fail("new_do_shell error: ~p~n",[Err]);
+
+ RecBin when Order==expect ; Order==expect_echo ->
+ ct:log("received ~p",[RecBin]),
+ RecStr = string:strip(unicode:characters_to_list(RecBin)),
+ ExpStr = string:strip(Arg),
+ case lists:prefix(ExpStr, RecStr) of
+ true when Order==expect ->
+ ct:log("Matched ~ts",[RecStr]),
+ new_do_shell(IO, N, More);
+ true when Order==expect_echo ->
+ ct:log("Matched echo ~ts",[RecStr]),
+ new_do_shell(IO, N, More);
+ false ->
+ ct:fail("*** Expected ~p, but got ~p",[string:strip(ExpStr),RecStr])
+ end
+ after 30000 ->
+ ct:log("Meassage queue of ~p:~n~p",
+ [self(), erlang:process_info(self(), messages)]),
+ case Order of
+ expect -> ct:fail("timeout, expected ~p",[string:strip(Arg)]);
+ type -> ct:fail("timeout, no prompt")
+ end
+ end;
+
+new_do_shell(_, _, []) ->
+ ok.
+
+prompt_prefix() ->
+ case node() of
+ nonode@nohost -> <<>>;
+ Node -> list_to_binary(
+ lists:concat(["(",Node,")"]))
end.
+
+new_do_shell_prompt(IO, N, type, Str, More) ->
+ ct:log("Matched prompt ~p to trigger sending of next line to server",[N]),
+ IO ! {input, self(), Str++"\r\n"},
+ ct:log("Promt '~p> ', Sent ~ts",[N,Str++"\r\n"]),
+ new_do_shell(IO, N, [{expect_echo,Str}|More]); % expect echo of the sent line
+new_do_shell_prompt(IO, N, Op, Str, More) ->
+ ct:log("Matched prompt ~p",[N]),
+ new_do_shell(IO, N, [{Op,Str}|More]).
+
+%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_basic_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_bench.spec b/lib/ssh/test/ssh_bench.spec
new file mode 100644
index 0000000000..029f0bd074
--- /dev/null
+++ b/lib/ssh/test/ssh_bench.spec
@@ -0,0 +1 @@
+{suites,"../ssh_test",[ssh_benchmark_SUITE]}.
diff --git a/lib/ssh/test/ssh_benchmark_SUITE.erl b/lib/ssh/test/ssh_benchmark_SUITE.erl
new file mode 100644
index 0000000000..e90bfa3d16
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE.erl
@@ -0,0 +1,539 @@
+%%%-------------------------------------------------------------------
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssh_benchmark_SUITE).
+-compile(export_all).
+
+-include_lib("common_test/include/ct_event.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+-include_lib("ssh/src/ssh.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_connect.hrl").
+-include_lib("ssh/src/ssh_userauth.hrl").
+
+
+suite() -> [{ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}].
+%%suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() -> [{group, opensshc_erld}
+%% {group, erlc_opensshd}
+ ].
+
+groups() ->
+ [{opensshc_erld, [{repeat, 3}], [openssh_client_shell,
+ openssh_client_sftp]}
+ ].
+
+
+init_per_suite(Config) ->
+ catch ssh:stop(),
+ catch crypto:stop(),
+ try
+ ok = crypto:start(),
+ report_client_algorithms(),
+ ok = ssh:start(),
+ {ok,TracerPid} = erlang_trace(),
+ [{tracer_pid,TracerPid} | init_sftp_dirs(Config)]
+ catch
+ C:E ->
+ {skip, io_lib:format("Couldn't start ~p:~p",[C,E])}
+ end.
+
+end_per_suite(_Config) ->
+ catch ssh:stop(),
+ catch crypto:stop(),
+ ok.
+
+
+
+init_per_group(opensshc_erld, Config) ->
+ case ssh_test_lib:ssh_type() of
+ openSSH ->
+ DataDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, UserDir),
+ ssh_test_lib:setup_rsa(DataDir, UserDir),
+ ssh_test_lib:setup_ecdsa("256", DataDir, UserDir),
+ Common = ssh_test_lib:intersect_bi_dir(
+ ssh_test_lib:intersection(ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshc))),
+ [{c_kexs, ssh_test_lib:sshc(kex)},
+ {c_ciphers, ssh_test_lib:sshc(cipher)},
+ {common_algs, Common}
+ | Config];
+ _ ->
+ {skip, "No OpenSsh client found"}
+ end;
+
+init_per_group(erlc_opensshd, _) ->
+ {skip, "Group erlc_opensshd not implemented"};
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, _Config) ->
+ ok.
+
+
+init_per_testcase(_Func, Conf) ->
+ Conf.
+
+end_per_testcase(_Func, _Conf) ->
+ ok.
+
+
+init_sftp_dirs(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ SrcDir = filename:join(UserDir, "sftp_src"),
+ ok = file:make_dir(SrcDir),
+ SrcFile = "big_data",
+ DstDir = filename:join(UserDir, "sftp_dst"),
+ ok = file:make_dir(DstDir),
+ N = 100 * 1024*1024,
+ ok = file:write_file(filename:join(SrcDir,SrcFile), crypto:rand_bytes(N)),
+ [{sftp_src_dir,SrcDir}, {sftp_dst_dir,DstDir}, {src_file,SrcFile}, {sftp_size,N}
+ | Config].
+
+%%%================================================================
+openssh_client_shell(Config) ->
+ lists:foreach(
+ fun(PrefAlgs=[{kex,[Kex]}]) when Kex == 'diffie-hellman-group-exchange-sha256' ->
+ lists:foreach(
+ fun(Grp) ->
+ openssh_client_shell(Config,
+ [{preferred_algorithms, PrefAlgs},
+ {dh_gex_groups, [Grp]}
+ ])
+ end, moduli());
+ (PrefAlgs) ->
+ openssh_client_shell(Config,
+ [{preferred_algorithms, PrefAlgs}])
+ end, variants(kex,Config) ++ variants(cipher,Config)
+ ).
+
+
+openssh_client_shell(Config, Options) ->
+ SystemDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ KnownHosts = filename:join(UserDir, "known_hosts"),
+
+ {ok, TracerPid} = erlang_trace(),
+ {ServerPid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {public_key_alg, ssh_dsa},
+ {failfun, fun ssh_test_lib:failfun/2} |
+ Options]),
+ ct:sleep(500),
+
+ Data = lists:duplicate(100000, $a),
+ Cmd = lists:concat(["ssh -p ",Port,
+ " -o UserKnownHostsFile=", KnownHosts,
+ " -o \"StrictHostKeyChecking no\"",
+ " localhost '\"",Data,"\"'."]),
+%% ct:pal("Cmd ="++Cmd),
+
+ Parent = self(),
+ SlavePid = spawn(fun() ->
+ Parent ! {self(),os:cmd(Cmd)}
+ end),
+ receive
+ {SlavePid, _ClientResponse} ->
+%% ct:pal("ClientResponse = ~p",[_ClientResponse]),
+ {ok, List} = get_trace_list(TracerPid),
+ Times = find_times(List, [accept_to_hello, kex, kex_to_auth, auth, to_prompt]),
+ Algs = find_algs(List),
+ ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
+ lists:foreach(
+ fun({Tag,Value,Unit}) ->
+ EventData =
+ case Tag of
+ {A,B} when A==encrypt ; A==decrypt ->
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Cipher ",A," ",B," [",Unit,"]"])}
+ ];
+ kex ->
+ KexAlgStr = fmt_alg(Algs#alg.kex, List),
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Erl server kex ",KexAlgStr," [",Unit,"]"])}
+ ];
+ _ when is_atom(Tag) ->
+ [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Erl server ",Tag," [",Unit,"]"])}
+ ]
+ end,
+ ct:pal("ct_event:notify ~p",[EventData]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = EventData})
+ end, Times),
+ ssh:stop_daemon(ServerPid),
+ ok
+ after 10000 ->
+ ssh:stop_daemon(ServerPid),
+ exit(SlavePid, kill),
+ {fail, timeout}
+ end.
+
+
+%%%================================================================
+openssh_client_sftp(Config) ->
+ lists:foreach(
+ fun(PrefAlgs) ->
+ openssh_client_sftp(Config, [{preferred_algorithms,PrefAlgs}])
+ end, variants(cipher,Config)).
+
+
+openssh_client_sftp(Config, Options) ->
+ SystemDir = ?config(data_dir, Config),
+ UserDir = ?config(priv_dir, Config),
+ SftpSrcDir = ?config(sftp_src_dir, Config),
+ SrcFile = ?config(src_file, Config),
+ SrcSize = ?config(sftp_size, Config),
+ KnownHosts = filename:join(UserDir, "known_hosts"),
+
+ {ok, TracerPid} = erlang_trace(),
+ {ServerPid, _Host, Port} =
+ ssh_test_lib:daemon([{system_dir, SystemDir},
+ {public_key_alg, ssh_dsa},
+ {subsystems,[ssh_sftpd:subsystem_spec([%{cwd, SftpSrcDir},
+ {root, SftpSrcDir}])]},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | Options]),
+ ct:sleep(500),
+ Cmd = lists:concat(["sftp",
+ " -b -",
+ " -P ",Port,
+ " -o UserKnownHostsFile=", KnownHosts,
+ " -o \"StrictHostKeyChecking no\"",
+ " localhost:",SrcFile
+ ]),
+%% ct:pal("Cmd = ~p",[Cmd]),
+
+ Parent = self(),
+ SlavePid = spawn(fun() ->
+ Parent ! {self(),os:cmd(Cmd)}
+ end),
+ receive
+ {SlavePid, _ClientResponse} ->
+ ct:pal("ClientResponse = ~p",[_ClientResponse]),
+ {ok, List} = get_trace_list(TracerPid),
+%%ct:pal("List=~p",[List]),
+ Times = find_times(List, [channel_open_close]),
+ Algs = find_algs(List),
+ ct:pal("Algorithms = ~p~n~nTimes = ~p",[Algs,Times]),
+ lists:foreach(
+ fun({{A,B},Value,Unit}) when A==encrypt ; A==decrypt ->
+ Data = [{value, Value},
+ {suite, ?MODULE},
+ {name, mk_name(["Sftp Cipher ",A," ",B," [",Unit,"]"])}
+ ],
+ ct:pal("sftp ct_event:notify ~p",[Data]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = Data});
+ ({channel_open_close,Value,Unit}) ->
+ Cipher = fmt_alg(Algs#alg.encrypt, List),
+ Data = [{value, round( (1024*Value) / SrcSize )},
+ {suite, ?MODULE},
+ {name, mk_name(["Sftp transfer ",Cipher," [",Unit," per kbyte]"])}
+ ],
+ ct:pal("sftp ct_event:notify ~p",[Data]),
+ ct_event:notify(#event{name = benchmark_data,
+ data = Data});
+ (_) ->
+ skip
+ end, Times),
+ ssh:stop_daemon(ServerPid),
+ ok
+ after 10000 ->
+ ssh:stop_daemon(ServerPid),
+ exit(SlavePid, kill),
+ {fail, timeout}
+ end.
+
+%%%================================================================
+variants(Tag, Config) ->
+ TagType =
+ case proplists:get_value(Tag, ssh:default_algorithms()) of
+ [{_,_}|_] -> one_way;
+ [A|_] when is_atom(A) -> two_way
+ end,
+ [ [{Tag,tag_value(TagType,Alg)}]
+ || Alg <- proplists:get_value(Tag, ?config(common_algs,Config))
+ ].
+
+tag_value(two_way, Alg) -> [Alg];
+tag_value(one_way, Alg) -> [{client2server,[Alg]},
+ {server2client,[Alg]}].
+
+%%%----------------------------------------------------------------
+fmt_alg(Alg, List) when is_atom(Alg) ->
+ fmt_alg(atom_to_list(Alg), List);
+fmt_alg(Alg = "diffie-hellman-group-exchange-sha" ++ _, List) ->
+ try
+ integer_to_list(find_gex_size_string(List))
+ of
+ GexSize -> lists:concat([Alg," ",GexSize])
+ catch
+ _:_ -> Alg
+ end;
+fmt_alg(Alg, _List) ->
+ Alg.
+
+%%%----------------------------------------------------------------
+mk_name(Name) -> [char(C) || C <- lists:concat(Name)].
+
+char($-) -> $_;
+char(C) -> C.
+
+%%%----------------------------------------------------------------
+find_times(L, Xs) ->
+ [find_time(X,L) || X <- Xs] ++
+ function_algs_times_sizes([{ssh_transport,encrypt,2},
+ {ssh_transport,decrypt,2},
+ {ssh_message,decode,1},
+ {ssh_message,encode,1}], L).
+
+-record(call, {
+ mfa,
+ pid,
+ t_call,
+ t_return,
+ args,
+ result
+ }).
+
+%%%----------------
+-define(send(M), fun(C=#call{mfa = {ssh_message,encode,1},
+ args = [M]}) ->
+ C#call.t_return
+ end).
+
+-define(recv(M), fun(C=#call{mfa = {ssh_message,decode,1},
+ result = M}) ->
+ C#call.t_call
+ end).
+
+find_time(accept_to_hello, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
+ C#call.t_call
+ end,
+ fun(C=#call{mfa = {ssh_connection_handler,hello,_},
+ args = [socket_control|_]}) ->
+ C#call.t_return
+ end
+ ], L, []),
+ {accept_to_hello, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(kex, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_connection_handler,hello,_},
+ args = [socket_control|_]}) ->
+ C#call.t_call
+ end,
+ ?send(#ssh_msg_newkeys{})
+ ], L, []),
+ {kex, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(kex_to_auth, L) ->
+ [T0,T1] = find([?send(#ssh_msg_newkeys{}),
+ ?recv(#ssh_msg_userauth_request{})
+ ], L, []),
+ {kex_to_auth, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(auth, L) ->
+ [T0,T1] = find([?recv(#ssh_msg_userauth_request{}),
+ ?send(#ssh_msg_userauth_success{})
+ ], L, []),
+ {auth, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(to_prompt, L) ->
+ [T0,T1] = find([fun(C=#call{mfa = {ssh_acceptor,handle_connection,5}}) ->
+ C#call.t_call
+ end,
+ ?recv(#ssh_msg_channel_request{request_type="env"})
+ ], L, []),
+ {to_prompt, now2micro_sec(now_diff(T1,T0)), microsec};
+find_time(channel_open_close, L) ->
+ [T0,T1] = find([?recv(#ssh_msg_channel_request{request_type="subsystem"}),
+ ?send(#ssh_msg_channel_close{})
+ ], L, []),
+ {channel_open_close, now2micro_sec(now_diff(T1,T0)), microsec}.
+
+
+
+find([F|Fs], [C|Cs], Acc) when is_function(F,1) ->
+ try
+ F(C)
+ of
+ T -> find(Fs, Cs, [T|Acc])
+ catch
+ _:_ -> find([F|Fs], Cs, Acc)
+ end;
+find([], _, Acc) ->
+ lists:reverse(Acc).
+
+
+find_algs(L) ->
+ {value, #call{result={ok,Algs}}} =
+ lists:keysearch({ssh_transport,select_algorithm,3}, #call.mfa, L),
+ Algs.
+
+find_gex_size_string(L) ->
+ %% server
+ {value, #call{result={ok,{Size, _}}}} =
+ lists:keysearch({public_key,dh_gex_group,4}, #call.mfa, L),
+ Size.
+
+%%%----------------
+function_algs_times_sizes(EncDecs, L) ->
+ Raw = [begin
+ {Tag,Size} = function_ats_result(EncDec, C),
+ {Tag, Size, now2micro_sec(now_diff(T1,T0))}
+ end
+ || EncDec <- EncDecs,
+ C = #call{mfa = ED,
+ args = Args, %%[S,Data],
+ t_call = T0,
+ t_return = T1} <- L,
+ ED == EncDec
+ ],
+ [{Alg, round(1024*Time/Size), "microsec per kbyte"} % Microseconds per 1k bytes.
+ || {Alg,Size,Time} <- lists:foldl(fun increment/2, [], Raw)].
+
+function_ats_result({ssh_transport,encrypt,2}, #call{args=[S,Data]}) ->
+ {{encrypt,S#ssh.encrypt}, size(Data)};
+function_ats_result({ssh_transport,decrypt,2}, #call{args=[S,Data]}) ->
+ {{decrypt,S#ssh.decrypt}, size(Data)};
+function_ats_result({ssh_message,encode,1}, #call{result=Data}) ->
+ {encode, size(Data)};
+function_ats_result({ssh_message,decode,1}, #call{args=[Data]}) ->
+ {decode, size(Data)}.
+
+
+increment({Alg,Sz,T}, [{Alg,SumSz,SumT}|Acc]) ->
+ [{Alg,SumSz+Sz,SumT+T} | Acc];
+increment(Spec, [X|Acc]) ->
+ [X | increment(Spec,Acc)]; % Not so many Alg, 2 or 3
+increment({Alg,Sz,T},[]) ->
+ [{Alg,Sz,T}].
+
+%%%----------------------------------------------------------------
+%%%
+%%% API for the traceing
+%%%
+get_trace_list(TracerPid) ->
+ TracerPid ! {get_trace_list,self()},
+ receive
+ {trace_list,L} -> {ok, pair_events(lists:reverse(L))}
+ after 5000 -> {error,no_reply}
+ end.
+
+erlang_trace() ->
+ TracerPid = spawn(fun trace_loop/0),
+ 0 = erlang:trace(new, true, [call,timestamp,{tracer,TracerPid}]),
+ [init_trace(MFA, tp(MFA))
+ || MFA <- [{ssh_acceptor,handle_connection,5},
+ {ssh_connection_handler,hello,2},
+ {ssh_message,encode,1},
+ {ssh_message,decode,1},
+ {ssh_transport,select_algorithm,3},
+ {ssh_transport,encrypt,2},
+ {ssh_transport,decrypt,2},
+ {ssh_message,encode,1},
+ {ssh_message,decode,1},
+ {public_key,dh_gex_group,4} % To find dh_gex group size
+ ]],
+ {ok, TracerPid}.
+
+tp({_M,_F,Arity}) ->
+ [{lists:duplicate(Arity,'_'), [], [{return_trace}]}].
+
+%%%----------------------------------------------------------------
+init_trace(MFA = {Module,_,_}, TP) ->
+ case code:is_loaded(Module) of
+ false -> code:load_file(Module);
+ _ -> ok
+ end,
+ erlang:trace_pattern(MFA, TP, [local]).
+
+
+trace_loop() ->
+ trace_loop([]).
+
+trace_loop(L) ->
+ receive
+ {get_trace_list, From} ->
+ From ! {trace_list, L},
+ trace_loop(L);
+ Ev ->
+ trace_loop([Ev|L])
+ end.
+
+pair_events(L) ->
+ pair_events(L, []).
+
+pair_events([{trace_ts,Pid,call,{M,F,Args},TS0} | L], Acc) ->
+ Arity = length(Args),
+ {ReturnValue,TS1} = find_return(Pid, {M,F,Arity}, L),
+ pair_events(L, [#call{mfa = {M,F,Arity},
+ pid = Pid,
+ t_call = TS0,
+ t_return = TS1,
+ args = Args,
+ result = ReturnValue} | Acc]);
+pair_events([_|L], Acc) ->
+ pair_events(L, Acc);
+pair_events([], Acc) ->
+ lists:reverse(Acc).
+
+
+find_return(Pid, MFA,
+ [{trace_ts, Pid, return_from, MFA, ReturnValue, TS}|_]) ->
+ {ReturnValue, TS};
+find_return(Pid, MFA, [_|L]) ->
+ find_return(Pid, MFA, L);
+find_return(_, _, []) ->
+ {undefined, undefined}.
+
+%%%----------------------------------------------------------------
+report_client_algorithms() ->
+ try
+ ssh_test_lib:extract_algos( ssh_test_lib:default_algorithms(sshc) )
+ of
+ ClientAlgs ->
+ ct:pal("The client supports:~n~p",[ClientAlgs])
+ catch
+ Cls:Err ->
+ ct:pal("Testing client about algorithms failed:~n~p ~p",[Cls,Err])
+ end.
+
+%%%----------------------------------------------------------------
+
+
+now2sec({A,B,C}) -> A*1000000 + B + C/1000000.
+
+now2micro_sec({A,B,C}) -> (A*1000000 + B)*1000000 + C.
+
+now_diff({A1,B1,C1}, {A0,B0,C0}) -> {A1-A0, B1-B0, C1-C0}.
+
+%%%================================================================
+moduli() ->
+ [{1023, 5, 16#CF973CD39DC7D62F2C45AAC5180491104C76E0FE5D80A10E6C06AE442F1F373167B0FCBC931F3C157B10A5557008FDE20D68051E6A4DB11CEE0B0749F76D7134B937A59DA998C42BC234A5C1A3CFCD70E624D253D7694076F7B1FD7B8D3427849C9377B3555796ACA58C69DFF542EEEC9859D3ADCE5CC88DF6F7817C9D182EB7},
+ {2047, 5, 16#F7693FC11FDDEAA493D3BA36F1FFF9264AA9952209203192A88A697BE9D0E306E306A27430BD87AB9EE9DB4BC78C41950C2EB0E5E4C686E8B1BA6D6A2B1FE91EF40C5EA32C51018323E1D305FE637F35ACABDBFC40AD683F779570A76869EB90015A342B2D1F7C81602688081FCAAA8D623090258D9C5C729C8CDDC0C12CA2D561DD987DB79B6AD7A2A509EBC383BF223FD95BC5A2FCC26FB3F3A0DD3FDC1228E338D3290235A596F9465F7BF490974847E616229A9E60B8F4AA161C52F655843CCCAE8821B40C426B535DE087964778652BBD4EC601C0456AE7128B593FCC64402C891227AE6EE88CC839416FBF462B4852999C646BE0BED7D8CF2BE5E381EF},
+ {4095, 2, 16#C8842271626E53546E0C712FA265713F2EE073C20A0723C96B6B182B1EAACC96233D4A199BD0E85F264078A513AD2454F284B8DF543D85019D1E70F2FF54BA43EFBC64AF465C170C3E376F5EC328F98E33E1ED8BED84FA097ABE584152B0E9827ED5CC2B1D4F5ECF2DC46F45C59816D02698EA26F319311E2B6973E83C37021CC8B416AEF653896A1764EE0CEE718A45E8B47CB960BD5907D0E843E8A8E7D4698363C3C3FB3ADC512368B72CAF16510C69052EA2AF51BE00BC8CA04DF1F00A00CC2CA4D74254A1E8738460FD244DDB446CB36554B0A24EEF3710E44DBCF39881E7D3F9AE223388084E7A49A3CB12612AE36416C0EB5628DF1477FEE4A5CF77CDC09AA0E2C989C0B7D1310AFA44B81DA79A65226C7EA510057991EABF9388DC5EA9F52FEA5D3B0872843F50878740794E523E9DC60E0EA1FC8746A7B2AA31FCA89AAA2FA907BED116C69D98F912DD5089BECF28577064225DE96FC214ED1794E7CCE8024F94036D915A123A464C951DA96A5ED7F286F205BEE71BDE2D133FD1891B31178FF25D31611A5B7839F0E68EAF0F8901A571E6917C580F31842A9F19C47E0638483B7947DDCD7864660AC2F8B2C430F1E7FC0F22FA51F96F0499332C5AD3FF9DC7F4332DD5BCCA820CC779B90C0F4C5F0CA52E96FAA187361753FBADC5C80D0492CD80A3EEA5D578772DA9FC1C0E10A0203098AF36D0ED2156BA7321EB},
+ {6143, 5, 16#FD9E6B52785CD7BE64D396A599DA4B97CD0BB49183F932A97694D80CA553354DBC26E77B8A0EC002257AADDF6AD27819CE64A06416E4A80B6EA92F28EA8D5B96C774109EEE5816B4B18F84368D1B41864C11AA73D6881675D779B174F6B4E344303F3EFD11BD7DE468467242372FD00908F296F5A2B20E2684F9122D08A46D647B05E298F0BCDAB60468349CCA6DA1B9FEBBC69D256FB9A3F1980F68466364FCEF1C98C1405191A6737A3627BA7F7313A8A18FC0B8521BF3430B1C6805CB44BCEB39904DD30130D24B225B598ED83C5FD757B80189FD9D5C2F9596687C40BAB1C6ED6244944629849D074A4C33FB15DDB3F9760FC59C44BEBB0EC032177147F61789769DAAAE2123CE488F7ECF19BDA051925BA9ED11EAA72DF70C9ECC8F714B4C35728E6679E66A1B56CCAE0FBBD3F9EBF950D4D623ED78E77CC3AD604E91F304EA78CE876F036214BD6F1977BD04C9ADD707D7A3BCCE87AD5D5A11C95E7025B0EA9C649DCB37942A3970A4FB04C284E4DDB4DC90163353B98B1C254FFD28443353F17A87C02E0BDB9F05424CC44C86309F1D73706F039CDAAC3EDC1A64F38FB42707D351DB5360C2680ADC1CC8D1C4AD312ACC904382C26BE33DA0E61429A5940820356ED28586BEB629ED1521D12D25B4DA01926295F3DA504DC9F431B719AC63277BE675E6F6DD4F7499CA11A23744577D653941963E8DAB610F7F226DB52CE5C683F72AEED2B6CE35ED07C29410397A6F7F606477CCC0EDE18CD0D96A7863BC4606193A8799B5AC1EEE6AC5EE36AC3077EC8DAB30EE94434B45B78BC13D96F74D6C4056EAA528CD3C68D308344808819B12F2BFB95A5C1A7DEEE188BF139216DDB7D757D7A50D3C46CE18881D776D617DCFFAA62276045373AA4D9446D7570338F99C0CA8A08851B4F9D388B4C275D3F9B7BA25F235D4329F63F7457C2EB5C68CE2A96D19766F0ED8E19F66DF3C5E29A38795B2F92291BB6EAB6F70A7E89DC9691F28486E9CF87FF11D5DF2E6B030A30B5D476AD59A34EE7262712ED96CEF4A5CAC3F08B3563D44683F746DA094C9CDB34427AF8D8CC2AE1B23C3BEB637},
+ {8191, 2, 16#DC61EF13E4F3FC10CC946EEABC33F83EFCB35E0F47E4EC25C1CCBB2C7B502B2EFB0691AA231C8476DD51BA73204E6EA10B1A970FE2CF14AF01E72E1AEA87519A91D00D1499189F94A6CDA9E29C05F11F17FE74A4919A710A2787E180744465DF81C62AA65662FDA46FA6175E8A31E5B29E66DED6701C8FC4217E91D733FE94380F046680967D4CEA7BAC8F3916CDF96AA2C474FAD9650F48403FD0B5B756D34667D36A07767FA33027AE55484D0F701C3CA16632F413A14E4B8645AFAF15B78978C19A7661EDC569BEC72394B1204B166A48FCD5F56BE29840C7794CA6D3440356F15858CDCA9B429C7EA92E17242893FDC8C9C63841A382C32F20CFAB121B4BCAFD7BF9EF07FBF7CDFFECA0CEF3A49C3E2B24FA836F3318435255655E1B281071F62D5E4CD63361299B7828F72936E3FEA9E8044562A6F6ADD5321187C3101E4669C6271598FE1A866C93FE2870A4CEB9254BA32A4719E439317EA42200A335B5CFFA7946A7D0F1BD1A69AA11288B73C71C80B77FE3707CB077DDDEA5CA36A449FAB230C9625A0B12F8275D3FF82F5DA380E7A3F11B6F155FE7E91AC960BD95D9B13F7423AB9B15CC3C4DC34EF296033F009468EA16A721AD659F56C18516025050749ABF05E6D3EBD9778142A530979291F46DAA399A86B7BCDF09CC3E6EEF101419762A306DB45AEFC96C64E83F28338D55905F6A387E0F515E580C3A9B35330E21C32198CDEE3AFB355967A098F635FCA7C49CB4E1E82464B2B390EF1F259E40B9A06235C0273F76284FE6BD534EF3AF7CB01A4A5252B8B94CADC2850B2E56D53F9A31D7C029DF967D0A30C05BC64E119BED6076818FABC8CDD93F3255693E14EFC1A740A5D63A5E847FFE87BAB1DDE0506E1762EA61EFA9F9756151ECCCADD91B98A961A901A2D8B01ABDDD29EC804E8C8D28214BBA26048F924CA66316696E51A49D02FF034D20E44914B1115339CAD3819E0CB1640F0084886FEDDE5E28C29DC48ED30A8C3D789734338F5A9DF42584326E536FD1CF30BC85B8DCBD6120D127C98FE4B3614074F13C2CA4854E6D794156C185C40EB3DA7619CE96ADAF0941BD5499848B034C2B11DFECC0BDFA81C594241F759EF53FC7CDE7F2DE4F23CF81A5A0B7D62E31DABB9198D40307F7824DD130B7D1B80E9B6D322FEEDB5ACE34944F0BFB7D016762A9B2E173BFDD69303766AFBAB45FAB75D05430B4A3515858C4B7F04E23414E4AD03842CB0A20D8FF4B59B7C852BA9A5BE982A8ADA5CB70C36CE2A4D2C31A7015C9F3275E43D192C1B2924424088907A057DA7F2D32A2149922AB2E33F2147D637A3508911CB3FEA5E1AAB4525BACF27B6DD7A3E0AFA978FC3A39DE8882FB22688C3CCC92B6E69ACB0BBF575AB3368E51A2F6A20C414C6F146727CC0045F29061E695D29F7C030CE6929EB3AD11A5CBD0CDEE37347869A3}].
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa b/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256
new file mode 100644
index 0000000000..4b1eb12eaa
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIJfCaBKIIKhjbJl5F8BedqlXOQYDX5ba9Skypllmx/w+oAoGCCqGSM49
+AwEHoUQDQgAE49RbK2xQ/19ji3uDPM7uT4692LbwWF1TiaA9vUuebMGazoW/98br
+N9xZu0L1AWwtEjs3kmJDTB7eJEGXnjUAcQ==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub
new file mode 100644
index 0000000000..a0147e60fa
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOPUWytsUP9fY4t7gzzO7k+Ovdi28FhdU4mgPb1LnmzBms6Fv/fG6zfcWbtC9QFsLRI7N5JiQ0we3iRBl541AHE= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384
new file mode 100644
index 0000000000..4e8aa40959
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDCYXb6OSAZyXRfLXOtMo43za197Hdc/T0YKjgQQjwDt6rlRwqTh7v7S
+PV2kXwNGdWigBwYFK4EEACKhZANiAARN2khlJUOOIiwsWHEALwDieeZR96qL4pUd
+ci7aeGaczdUK5jOA9D9zmBZtSYTfO8Cr7ekVghDlcWAIJ/BXcswgQwSEQ6wyfaTF
+8FYfyr4l3u9IirsnyaFzeIgeoNis8Gw=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub
new file mode 100644
index 0000000000..41e722e545
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBE3aSGUlQ44iLCxYcQAvAOJ55lH3qovilR1yLtp4ZpzN1QrmM4D0P3OYFm1JhN87wKvt6RWCEOVxYAgn8FdyzCBDBIRDrDJ9pMXwVh/KviXe70iKuyfJoXN4iB6g2KzwbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521 b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521
new file mode 100644
index 0000000000..7196f46e97
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEFMadoz4ckEcClfqXa2tiUuYkJdDfwq+/iFQcpt8ESuEd26IY/vm47Q
+9UzbPkO4ou8xkNsQ3WvCRQBBWtn5O2kUU6AHBgUrgQQAI6GBiQOBhgAEAde5BRu5
+01/jS0jRk212xsb2DxPrxNpgp6IMCV8TA4Eps+8bSqHB091nLiBcP422HXYfuCd7
+XDjSs8ihcmhp0hCRASLqZR9EzW9W/SOt876May1Huj5X+WSO6RLe7vPn9vmf7kHf
+pip6m7M7qp2qGgQ3q2vRwS2K/O6156ohiOlmuuFs
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub
new file mode 100644
index 0000000000..8f059120bc
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_ecdsa521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHXuQUbudNf40tI0ZNtdsbG9g8T68TaYKeiDAlfEwOBKbPvG0qhwdPdZy4gXD+Nth12H7gne1w40rPIoXJoadIQkQEi6mUfRM1vVv0jrfO+jGstR7o+V/lkjukS3u7z5/b5n+5B36YqepuzO6qdqhoEN6tr0cEtivzuteeqIYjpZrrhbA== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa b/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256
new file mode 100644
index 0000000000..2979ea88ed
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMe4MDoit0t8RzSVPwkCBemQ9fhXL+xnTSAWISw8HNCioAoGCCqGSM49
+AwEHoUQDQgAEo2q7U3P6r0W5WGOLtM78UQtofM9UalEhiZeDdiyylsR/RR17Op0s
+VPGSADLmzzgcucLEKy17j2S+oz42VUJy5A==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub
new file mode 100644
index 0000000000..85dc419345
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key256.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKNqu1Nz+q9FuVhji7TO/FELaHzPVGpRIYmXg3YsspbEf0UdezqdLFTxkgAy5s84HLnCxCste49kvqM+NlVCcuQ= uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384
new file mode 100644
index 0000000000..fb1a862ded
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDArxbDfh3p1okrD9wQw6jJ4d4DdlBPD5GqXE8bIeRJiK41Sh40LgvPw
+mkqEDSXK++CgBwYFK4EEACKhZANiAAScl43Ih2lWTDKrSox5ve5uiTXil4smsup3
+CfS1XPjKxgBAmlfBim8izbdrT0BFdQzz2joduNMtpt61wO4rGs6jm0UP7Kim9PC7
+Hneb/99fIYopdMH5NMnk60zGO1uZ2vc=
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub
new file mode 100644
index 0000000000..428d5fb7d7
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key384.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBJyXjciHaVZMMqtKjHm97m6JNeKXiyay6ncJ9LVc+MrGAECaV8GKbyLNt2tPQEV1DPPaOh240y2m3rXA7isazqObRQ/sqKb08Lsed5v/318hiil0wfk0yeTrTMY7W5na9w== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521 b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521
new file mode 100644
index 0000000000..3e51ec2ecd
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIB8O1BFkl2HQjQLRLonEZ97da/h39DMa9/0/hvPZWAI8gUPEQcHxRx
+U7b09p3Zh+EBbMFq8+1ae9ds+ZTxE4WFSvKgBwYFK4EEACOhgYkDgYYABAAlWVjq
+Bzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/
+vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5
+ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg==
+-----END EC PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub
new file mode 100644
index 0000000000..017a29f4da
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_ecdsa_key521.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAAlWVjqBzg7Wt4gE6UNb1lRE2cnlmH2L/A5uo6qZRx5lPnSKOxEhxSb/Oay1+9d6KRdrh6/vlhd9SHDBhLcAPDvWgBnJIEj92Q3pXX4JtoitL0yl+SvvU+vUh966mzHShHzj8p5ccOgPkPNoA70yrpGzkIhPezpZOQdCaOXj/jFqNCTDg== uabhnil@elxadlj3q32
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_benchmark_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index e3871b3feb..1b93cc9c32 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -21,6 +22,7 @@
-module(ssh_connection_SUITE).
-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_connect.hrl").
-compile(export_all).
@@ -46,7 +48,8 @@ all() ->
gracefull_invalid_long_start,
gracefull_invalid_long_start_no_nl,
stop_listener,
- start_subsystem_on_closed_channel
+ start_subsystem_on_closed_channel,
+ max_channels_option
].
groups() ->
[{openssh, [], payload() ++ ptty()}].
@@ -64,6 +67,7 @@ ptty() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+ catch crypto:stop(),
case catch crypto:start() of
ok ->
Config;
@@ -75,12 +79,13 @@ end_per_suite(_Config) ->
crypto:stop().
%%--------------------------------------------------------------------
-init_per_group(openssh, _Config) ->
+init_per_group(openssh, Config) ->
case gen_tcp:connect("localhost", 22, []) of
{error,econnrefused} ->
{skip,"No openssh deamon"};
{ok, Socket} ->
- gen_tcp:close(Socket)
+ gen_tcp:close(Socket),
+ ssh_test_lib:openssh_sanity_check(Config)
end;
init_per_group(_, Config) ->
Config.
@@ -92,7 +97,7 @@ end_per_group(_, Config) ->
init_per_testcase(_TestCase, Config) ->
%% To make sure we start clean as it is not certain that
%% end_per_testcase will be run!
- ssh:stop(),
+ end_per_testcase(Config),
ssh:start(),
Config.
@@ -115,20 +120,28 @@ simple_exec(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, <<"testing\n">>}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -150,20 +163,28 @@ small_cat(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {data, ChannelId0, 0, Data}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
%% receive close messages
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
big_cat() ->
@@ -182,7 +203,7 @@ big_cat(Config) when is_list(Config) ->
%% pre-adjust receive window so the other end doesn't block
ssh_connection:adjust_window(ConnectionRef, ChannelId0, size(Data)),
- ct:pal("sending ~p byte binary~n",[size(Data)]),
+ ct:log("sending ~p byte binary~n",[size(Data)]),
ok = ssh_connection:send(ConnectionRef, ChannelId0, Data, 10000),
ok = ssh_connection:send_eof(ConnectionRef, ChannelId0),
@@ -193,10 +214,10 @@ big_cat(Config) when is_list(Config) ->
{ok, Other} ->
case size(Data) =:= size(Other) of
true ->
- ct:pal("received and sent data are same"
+ ct:log("received and sent data are same"
"size but do not match~n",[]);
false ->
- ct:pal("sent ~p but only received ~p~n",
+ ct:log("sent ~p but only received ~p~n",
[size(Data), size(Other)])
end,
ct:fail(receive_data_mismatch);
@@ -207,11 +228,15 @@ big_cat(Config) when is_list(Config) ->
%% receive close messages (eof already consumed)
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}} ->
- ok
+ ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
@@ -230,14 +255,20 @@ send_after_exit(Config) when is_list(Config) ->
receive
{ssh_cm, ConnectionRef, {eof, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef, {exit_status, ChannelId0, _ExitStatus}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
receive
{ssh_cm, ConnectionRef,{closed, ChannelId0}} ->
ok
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
case ssh_connection:send(ConnectionRef, ChannelId0, Data, 2000) of
{error, closed} -> ok;
@@ -269,7 +300,7 @@ ptty_alloc(Config) when is_list(Config) ->
{user_interaction, false}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
- [{term, default_term()}, {width, 70}, {high, 20}]),
+ [{term, os:getenv("TERM", ?DEFAULT_TERMINAL)}, {width, 70}, {height, 20}]),
ssh:close(ConnectionRef).
@@ -282,7 +313,7 @@ ptty_alloc_pixel(Config) when is_list(Config) ->
{user_interaction, false}]),
{ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId,
- [{term, default_term()}, {pixel_widh, 630}, {pixel_hight, 470}]),
+ [{term, os:getenv("TERM", ?DEFAULT_TERMINAL)}, {pixel_widh, 630}, {pixel_hight, 470}]),
ssh:close(ConnectionRef).
%%--------------------------------------------------------------------
@@ -446,11 +477,13 @@ gracefull_invalid_version(Config) when is_list(Config) ->
ok = gen_tcp:send(S, ["SSH-8.-1","\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_start(Config) when is_list(Config) ->
@@ -466,11 +499,13 @@ gracefull_invalid_start(Config) when is_list(Config) ->
ok = gen_tcp:send(S, ["foobar","\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
gracefull_invalid_long_start(Config) when is_list(Config) ->
@@ -486,11 +521,13 @@ gracefull_invalid_long_start(Config) when is_list(Config) ->
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -507,11 +544,13 @@ gracefull_invalid_long_start_no_nl(Config) when is_list(Config) ->
ok = gen_tcp:send(S, [lists:duplicate(257, $a), "\r\n"]),
receive
Verstring ->
- ct:pal("Server version: ~p~n", [Verstring]),
+ ct:log("Server version: ~p~n", [Verstring]),
receive
{tcp_closed, S} ->
ok
end
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
stop_listener() ->
@@ -602,6 +641,88 @@ start_subsystem_on_closed_channel(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
+max_channels_option() ->
+ [{doc, "Test max_channels option"}].
+
+max_channels_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {max_channels, 3},
+ {subsystems, [{"echo_n", {ssh_echo_server, [4000000]}}]}
+ ]),
+
+ ConnectionRef = ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, true},
+ {user_dir, UserDir}]),
+
+ {ok, ChannelId0} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId1} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId2} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId3} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId4} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, ChannelId5} = ssh_connection:session_channel(ConnectionRef, infinity),
+ {ok, _ChannelId6} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ %%%---- shell
+ ok = ssh_connection:shell(ConnectionRef,ChannelId0),
+ receive
+ {ssh_cm,ConnectionRef, {data, ChannelId0, 0, <<"Eshell",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("CLI Timeout")
+ end,
+
+ %%%---- subsystem "echo_n"
+ success = ssh_connection:subsystem(ConnectionRef, ChannelId1, "echo_n", infinity),
+
+ %%%---- exec #1
+ success = ssh_connection:exec(ConnectionRef, ChannelId2, "testing1.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId2, 0, <<"testing1",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #1 Timeout")
+ end,
+
+ %%%---- ptty
+ success = ssh_connection:ptty_alloc(ConnectionRef, ChannelId3, []),
+
+ %%%---- exec #2
+ failure = ssh_connection:exec(ConnectionRef, ChannelId4, "testing2.\n", infinity),
+
+ %%%---- close the shell
+ ok = ssh_connection:send(ConnectionRef, ChannelId0, "exit().\n", 5000),
+
+ %%%---- wait for the subsystem to terminate
+ receive
+ {ssh_cm,ConnectionRef,{closed,ChannelId0}} -> ok
+ after 5000 ->
+ ct:log("Timeout waiting for '{ssh_cm,~p,{closed,~p}}'~n"
+ "Message queue:~n~p",
+ [ConnectionRef,ChannelId0,erlang:process_info(self(),messages)]),
+ ct:fail("exit Timeout",[])
+ end,
+
+ %%%---- exec #3
+ success = ssh_connection:exec(ConnectionRef, ChannelId5, "testing3.\n", infinity),
+ receive
+ {ssh_cm, ConnectionRef, {data, ChannelId5, 0, <<"testing3",_/binary>>}} ->
+ ok
+ after 5000 ->
+ ct:fail("Exec #3 Timeout")
+ end,
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
big_cat_rx(ConnectionRef, ChannelId) ->
@@ -647,11 +768,3 @@ ssh_exec(Cmd) ->
spawn(fun() ->
io:format(Cmd ++ "\n")
end).
-
-default_term() ->
- case os:getenv("TERM") of
- false ->
- "vt100";
- Str when is_list(Str)->
- Str
- end.
diff --git a/lib/ssh/test/ssh_echo_server.erl b/lib/ssh/test/ssh_echo_server.erl
index 315ffecfd7..96c9aad135 100644
--- a/lib/ssh/test/ssh_echo_server.erl
+++ b/lib/ssh/test/ssh_echo_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/ssh_key_cb.erl b/lib/ssh/test/ssh_key_cb.erl
new file mode 100644
index 0000000000..388ec2ecc1
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb.erl
@@ -0,0 +1,45 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ UserDir = proplists:get_value(user_dir, Opts),
+ KeyFile = filename:join(filename:dirname(UserDir), "id_dsa"),
+ {ok, KeyBin} = file:read_file(KeyFile),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_key_cb_options.erl b/lib/ssh/test/ssh_key_cb_options.erl
new file mode 100644
index 0000000000..afccb34f0f
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb_options.erl
@@ -0,0 +1,44 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb_options).
+-behaviour(ssh_client_key_api).
+-compile(export_all).
+
+add_host_key(_, _, _) ->
+ ok.
+
+is_host_key(_, _, _, _) ->
+ true.
+
+user_key('ssh-dss', Opts) ->
+ KeyCbOpts = proplists:get_value(key_cb_private, Opts),
+ KeyBin = proplists:get_value(priv_key, KeyCbOpts),
+ [Entry] = public_key:pem_decode(KeyBin),
+ Key = public_key:pem_entry_decode(Entry),
+ {ok, Key};
+
+user_key(_Alg, _Opt) ->
+ {error, "Not Supported"}.
diff --git a/lib/ssh/test/ssh_options_SUITE.erl b/lib/ssh/test/ssh_options_SUITE.erl
new file mode 100644
index 0000000000..6a201d401f
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE.erl
@@ -0,0 +1,1191 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_options_SUITE).
+
+%%% This test suite tests different options for the ssh functions
+
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/file.hrl").
+
+
+%%% Test cases
+-export([connectfun_disconnectfun_client/1,
+ disconnectfun_option_client/1,
+ disconnectfun_option_server/1,
+ id_string_no_opt_client/1,
+ id_string_no_opt_server/1,
+ id_string_own_string_client/1,
+ id_string_own_string_server/1,
+ id_string_random_client/1,
+ id_string_random_server/1,
+ max_sessions_sftp_start_channel_parallel/1,
+ max_sessions_sftp_start_channel_sequential/1,
+ max_sessions_ssh_connect_parallel/1,
+ max_sessions_ssh_connect_sequential/1,
+ server_password_option/1,
+ server_userpassword_option/1,
+ server_pwdfun_option/1,
+ server_pwdfun_4_option/1,
+ server_pwdfun_4_option_repeat/1,
+ ssh_connect_arg4_timeout/1,
+ ssh_connect_negtimeout_parallel/1,
+ ssh_connect_negtimeout_sequential/1,
+ ssh_connect_nonegtimeout_connected_parallel/1,
+ ssh_connect_nonegtimeout_connected_sequential/1,
+ ssh_connect_timeout/1, connect/4,
+ ssh_daemon_minimal_remote_max_packet_size_option/1,
+ ssh_msg_debug_fun_option_client/1,
+ ssh_msg_debug_fun_option_server/1,
+ system_dir_option/1,
+ unexpectedfun_option_client/1,
+ unexpectedfun_option_server/1,
+ user_dir_option/1,
+ connectfun_disconnectfun_server/1
+ ]).
+
+%%% Common test callbacks
+-export([suite/0, all/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_group/2, end_per_group/2,
+ init_per_testcase/2, end_per_testcase/2
+ ]).
+
+
+-define(NEWLINE, <<"\r\n">>).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [connectfun_disconnectfun_server,
+ connectfun_disconnectfun_client,
+ server_password_option,
+ server_userpassword_option,
+ server_pwdfun_option,
+ server_pwdfun_4_option,
+ server_pwdfun_4_option_repeat,
+ {group, dir_options},
+ ssh_connect_timeout,
+ ssh_connect_arg4_timeout,
+ ssh_daemon_minimal_remote_max_packet_size_option,
+ ssh_msg_debug_fun_option_client,
+ ssh_msg_debug_fun_option_server,
+ disconnectfun_option_server,
+ disconnectfun_option_client,
+ unexpectedfun_option_server,
+ unexpectedfun_option_client,
+ id_string_no_opt_client,
+ id_string_own_string_client,
+ id_string_random_client,
+ id_string_no_opt_server,
+ id_string_own_string_server,
+ id_string_random_server,
+ {group, hardening_tests}
+ ].
+
+groups() ->
+ [{hardening_tests, [], [ssh_connect_nonegtimeout_connected_parallel,
+ ssh_connect_nonegtimeout_connected_sequential,
+ ssh_connect_negtimeout_parallel,
+ ssh_connect_negtimeout_sequential,
+ max_sessions_ssh_connect_parallel,
+ max_sessions_ssh_connect_sequential,
+ max_sessions_sftp_start_channel_parallel,
+ max_sessions_sftp_start_channel_sequential
+ ]},
+ {dir_options, [], [user_dir_option,
+ system_dir_option]}
+ ].
+
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ case catch crypto:start() of
+ ok ->
+ Config;
+ _Else ->
+ {skip, "Crypto could not be started!"}
+ end.
+end_per_suite(_Config) ->
+ ssh:stop(),
+ crypto:stop().
+%%--------------------------------------------------------------------
+init_per_group(hardening_tests, Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_dsa(DataDir, PrivDir),
+ Config;
+init_per_group(dir_options, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ %% Make unreadable dir:
+ Dir_unreadable = filename:join(PrivDir, "unread"),
+ ok = file:make_dir(Dir_unreadable),
+ {ok,F1} = file:read_file_info(Dir_unreadable),
+ ok = file:write_file_info(Dir_unreadable,
+ F1#file_info{mode = F1#file_info.mode band (bnot 8#00444)}),
+ %% Make readable file:
+ File_readable = filename:join(PrivDir, "file"),
+ ok = file:write_file(File_readable, <<>>),
+
+ %% Check:
+ case {file:read_file_info(Dir_unreadable),
+ file:read_file_info(File_readable)} of
+ {{ok, Id=#file_info{type=directory, access=Md}},
+ {ok, If=#file_info{type=regular, access=Mf}}} ->
+ AccessOK =
+ case {Md, Mf} of
+ {read, _} -> false;
+ {read_write, _} -> false;
+ {_, read} -> true;
+ {_, read_write} -> true;
+ _ -> false
+ end,
+
+ case AccessOK of
+ true ->
+ %% Save:
+ [{unreadable_dir, Dir_unreadable},
+ {readable_file, File_readable}
+ | Config];
+ false ->
+ ct:log("File#file_info : ~p~n"
+ "Dir#file_info : ~p",[If,Id]),
+ {skip, "File or dir mode settings failed"}
+ end;
+
+ NotDirFile ->
+ ct:log("{Dir,File} -> ~p",[NotDirFile]),
+ {skip, "File/Dir creation failed"}
+ end;
+init_per_group(_, Config) ->
+ Config.
+
+end_per_group(_, Config) ->
+ Config.
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ ssh:start(),
+ Config.
+
+end_per_testcase(TestCase, Config) when TestCase == server_password_option;
+ TestCase == server_userpassword_option;
+ TestCase == server_pwdfun_option;
+ TestCase == server_pwdfun_4_option ->
+ UserDir = filename:join(?config(priv_dir, Config), nopubkey),
+ ssh_test_lib:del_dirs(UserDir),
+ end_per_testcase(Config);
+end_per_testcase(_TestCase, Config) ->
+ end_per_testcase(Config).
+
+end_per_testcase(_Config) ->
+ ssh:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%%% validate to server that uses the 'password' option
+server_password_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"}]),
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ ct:log("Test of wrong password: Error msg: ~p ~n", [Reason]),
+
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% validate to server that uses the 'password' option
+server_userpassword_option(Config) when is_list(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {user_passwords, [{"vego", "morot"}]}]),
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun' option
+server_pwdfun_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ CHKPWD = fun("foo",Pwd) -> Pwd=="bar";
+ (_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,CHKPWD}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+%%% validate to server that uses the 'pwdfun/4' option
+server_pwdfun_4_option(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ PWDFUN = fun("foo",Pwd,{_,_},undefined) -> Pwd=="bar";
+ ("fie",Pwd,{_,_},undefined) -> {Pwd=="bar",new_state};
+ ("bandit",_,_,_) -> disconnect;
+ (_,_,_,_) -> false
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {pwdfun,PWDFUN}]),
+ ConnectionRef1 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef1),
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "bar"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+
+ Reason = "Unable to connect using the available authentication methods",
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "fie"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "vego"},
+ {password, "foo"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+
+ {error, Reason} =
+ ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "bandit"},
+ {password, "pwd breaking"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
+ ssh:stop_daemon(Pid).
+
+
+%%--------------------------------------------------------------------
+server_pwdfun_4_option_repeat(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+ %% Test that the state works
+ Parent = self(),
+ PWDFUN = fun("foo",P="bar",_,S) -> Parent!{P,S},true;
+ (_,P,_,S=undefined) -> Parent!{P,S},{false,1};
+ (_,P,_,S) -> Parent!{P,S}, {false,S+1}
+ end,
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {auth_methods,"keyboard-interactive"},
+ {pwdfun,PWDFUN}]),
+
+ %% Try with passwords "incorrect", "Bad again" and finally "bar"
+ KIFFUN = fun(_,_,_) ->
+ K={k,self()},
+ case get(K) of
+ undefined ->
+ put(K,1),
+ ["incorrect"];
+ 2 ->
+ put(K,3),
+ ["bar"];
+ S->
+ put(K,S+1),
+ ["Bad again"]
+ end
+ end,
+
+ ConnectionRef2 =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {keyboard_interact_fun, KIFFUN},
+ {user_dir, UserDir}]),
+ ssh:close(ConnectionRef2),
+ ssh:stop_daemon(Pid),
+
+ lists:foreach(fun(Expect) ->
+ receive
+ Expect -> ok;
+ Other -> ct:fail("Expect: ~p~nReceived ~p",[Expect,Other])
+ after
+ 2000 -> ct:fail("Timeout expecting ~p",[Expect])
+ end
+ end, [{"incorrect",undefined},
+ {"Bad again",1},
+ {"bar",2}]).
+
+%%--------------------------------------------------------------------
+system_dir_option(Config) ->
+ DirUnread = proplists:get_value(unreadable_dir,Config),
+ FileRead = proplists:get_value(readable_file,Config),
+
+ case ssh_test_lib:daemon([{system_dir, DirUnread}]) of
+ {error,{eoptions,{{system_dir,DirUnread},eacces}}} ->
+ ok;
+ {Pid1,_Host1,Port1} when is_pid(Pid1),is_integer(Port1) ->
+ ssh:stop_daemon(Pid1),
+ ct:fail("Didn't detect that dir is unreadable", [])
+ end,
+
+ case ssh_test_lib:daemon([{system_dir, FileRead}]) of
+ {error,{eoptions,{{system_dir,FileRead},enotdir}}} ->
+ ok;
+ {Pid2,_Host2,Port2} when is_pid(Pid2),is_integer(Port2) ->
+ ssh:stop_daemon(Pid2),
+ ct:fail("Didn't detect that option is a plain file", [])
+ end.
+
+
+user_dir_option(Config) ->
+ DirUnread = proplists:get_value(unreadable_dir,Config),
+ FileRead = proplists:get_value(readable_file,Config),
+ %% Any port will do (beware, implementation knowledge!):
+ Port = 65535,
+
+ case ssh:connect("localhost", Port, [{user_dir, DirUnread}]) of
+ {error,{eoptions,{{user_dir,DirUnread},eacces}}} ->
+ ok;
+ {error,econnrefused} ->
+ ct:fail("Didn't detect that dir is unreadable", [])
+ end,
+
+ case ssh:connect("localhost", Port, [{user_dir, FileRead}]) of
+ {error,{eoptions,{{user_dir,FileRead},enotdir}}} ->
+ ok;
+ {error,econnrefused} ->
+ ct:fail("Didn't detect that option is a plain file", [])
+ end.
+
+%%--------------------------------------------------------------------
+%%% validate client that uses the 'ssh_msg_debug_fun' option
+ssh_msg_debug_fun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ Parent = self(),
+ DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
+
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {ssh_msg_debug_fun,DbgFun}]),
+ %% Beware, implementation knowledge:
+ gen_fsm:send_all_state_event(ConnectionRef,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
+ receive
+ {msg_dbg,X={ConnectionRef,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got expected dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid);
+ {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got dbg msg but bad ConnectionRef (~p expected) ~p",[ConnectionRef,X]),
+ ssh:stop_daemon(Pid),
+ {fail, "Bad ConnectionRef received"};
+ {msg_dbg,X} ->
+ ct:log("Got bad dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid),
+ {fail,"Bad msg received"}
+ after 1000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+connectfun_disconnectfun_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ Ref = make_ref(),
+ ConnFun = fun(_,_,_) -> Parent ! {connect,Ref} end,
+ DiscFun = fun(R) -> Parent ! {disconnect,Ref,R} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {disconnectfun, DiscFun},
+ {connectfun, ConnFun}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connect,Ref} ->
+ ssh:close(ConnectionRef),
+ receive
+ {disconnect,Ref,R} ->
+ ct:log("Disconnect result: ~p",[R]),
+ ssh:stop_daemon(Pid)
+ after 2000 ->
+ {fail, "No disconnectfun action"}
+ end
+ after 2000 ->
+ {fail, "No connectfun action"}
+ end.
+
+%%--------------------------------------------------------------------
+connectfun_disconnectfun_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ Ref = make_ref(),
+ DiscFun = fun(R) -> Parent ! {disconnect,Ref,R} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {disconnectfun, DiscFun},
+ {user_interaction, false}]),
+ ssh:stop_daemon(Pid),
+ receive
+ {disconnect,Ref,R} ->
+ ct:log("Disconnect result: ~p",[R])
+ after 2000 ->
+ {fail, "No disconnectfun action"}
+ end.
+
+%%--------------------------------------------------------------------
+%%% validate client that uses the 'ssh_msg_debug_fun' option
+ssh_msg_debug_fun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DbgFun = fun(ConnRef,Displ,Msg,Lang) -> Parent ! {msg_dbg,{ConnRef,Displ,Msg,Lang}} end,
+ ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {connectfun, ConnFun},
+ {ssh_msg_debug_fun, DbgFun}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connection_pid,Server} ->
+ %% Beware, implementation knowledge:
+ gen_fsm:send_all_state_event(Server,{ssh_msg_debug,false,<<"Hello">>,<<>>}),
+ receive
+ {msg_dbg,X={_,false,<<"Hello">>,<<>>}} ->
+ ct:log("Got expected dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid);
+ {msg_dbg,X} ->
+ ct:log("Got bad dbg msg ~p",[X]),
+ ssh:stop_daemon(Pid),
+ {fail,"Bad msg received"}
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout2}
+ end
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout1}
+ end.
+
+%%--------------------------------------------------------------------
+disconnectfun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DisConnFun = fun(Reason) -> Parent ! {disconnect,Reason} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {disconnectfun, DisConnFun}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ ssh:close(ConnectionRef),
+ receive
+ {disconnect,Reason} ->
+ ct:log("Server detected disconnect: ~p",[Reason]),
+ ssh:stop_daemon(Pid),
+ ok
+ after 3000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
+ {fail,"Timeout waiting for disconnect"}
+ end.
+
+%%--------------------------------------------------------------------
+disconnectfun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ DisConnFun = fun(Reason) -> Parent ! {disconnect,Reason} end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {disconnectfun, DisConnFun}]),
+ ssh:stop_daemon(Pid),
+ receive
+ {disconnect,Reason} ->
+ ct:log("Client detected disconnect: ~p",[Reason]),
+ ok
+ after 3000 ->
+ receive
+ X -> ct:log("received ~p",[X])
+ after 0 -> ok
+ end,
+ {fail,"Timeout waiting for disconnect"}
+ end.
+
+%%--------------------------------------------------------------------
+unexpectedfun_option_server(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ ConnFun = fun(_,_,_) -> Parent ! {connection_pid,self()} end,
+ UnexpFun = fun(Msg,Peer) ->
+ Parent ! {unexpected,Msg,Peer,self()},
+ skip
+ end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {connectfun, ConnFun},
+ {unexpectedfun, UnexpFun}]),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false}]),
+ receive
+ {connection_pid,Server} ->
+ %% Beware, implementation knowledge:
+ Server ! unexpected_message,
+ receive
+ {unexpected, unexpected_message, {{_,_,_,_},_}, _} -> ok;
+ {unexpected, unexpected_message, Peer, _} -> ct:fail("Bad peer ~p",[Peer]);
+ M = {unexpected, _, _, _} -> ct:fail("Bad msg ~p",[M])
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout2}
+ end
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout1}
+ end.
+
+%%--------------------------------------------------------------------
+unexpectedfun_option_client(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ SysDir = ?config(data_dir, Config),
+
+ Parent = self(),
+ UnexpFun = fun(Msg,Peer) ->
+ Parent ! {unexpected,Msg,Peer,self()},
+ skip
+ end,
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, UserDir},
+ {password, "morot"},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user, "foo"},
+ {password, "morot"},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {unexpectedfun, UnexpFun}]),
+ %% Beware, implementation knowledge:
+ ConnectionRef ! unexpected_message,
+
+ receive
+ {unexpected, unexpected_message, {{_,_,_,_},_}, ConnectionRef} ->
+ ok;
+ {unexpected, unexpected_message, Peer, ConnectionRef} ->
+ ct:fail("Bad peer ~p",[Peer]);
+ M = {unexpected, _, _, _} ->
+ ct:fail("Bad msg ~p",[M])
+ after 3000 ->
+ ssh:stop_daemon(Pid),
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test connect_timeout option in ssh:connect/4
+ssh_connect_timeout(_Config) ->
+ ConnTimeout = 2000,
+ {error,{faked_transport,connect,TimeoutToTransport}} =
+ ssh:connect("localhost", 12345,
+ [{transport,{tcp,?MODULE,tcp_closed}},
+ {connect_timeout,ConnTimeout}],
+ 1000),
+ case TimeoutToTransport of
+ ConnTimeout -> ok;
+ Other ->
+ ct:log("connect_timeout is ~p but transport received ~p",[ConnTimeout,Other]),
+ {fail,"ssh:connect/4 wrong connect_timeout received in transport"}
+ end.
+
+%% Plugin function for the test above
+connect(_Host, _Port, _Opts, Timeout) ->
+ {error, {faked_transport,connect,Timeout}}.
+
+%%--------------------------------------------------------------------
+%%% Test fourth argument in ssh:connect/4
+ssh_connect_arg4_timeout(_Config) ->
+ Timeout = 1000,
+ Parent = self(),
+ %% start the server
+ Server = spawn(fun() ->
+ {ok,Sl} = gen_tcp:listen(0,[]),
+ {ok,{_,Port}} = inet:sockname(Sl),
+ Parent ! {port,self(),Port},
+ Rsa = gen_tcp:accept(Sl),
+ ct:log("Server gen_tcp:accept got ~p",[Rsa]),
+ receive after 2*Timeout -> ok end %% let client timeout first
+ end),
+
+ %% Get listening port
+ Port = receive
+ {port,Server,ServerPort} -> ServerPort
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end,
+
+ %% try to connect with a timeout, but "supervise" it
+ Client = spawn(fun() ->
+ T0 = erlang:monotonic_time(),
+ Rc = ssh:connect("localhost",Port,[],Timeout),
+ ct:log("Client ssh:connect got ~p",[Rc]),
+ Parent ! {done,self(),Rc,T0}
+ end),
+
+ %% Wait for client reaction on the connection try:
+ receive
+ {done, Client, {error,timeout}, T0} ->
+ Msp = ms_passed(T0),
+ exit(Server,hasta_la_vista___baby),
+ Low = 0.9*Timeout,
+ High = 2.5*Timeout,
+ ct:log("Timeout limits: ~.4f - ~.4f ms, timeout "
+ "was ~.4f ms, expected ~p ms",[Low,High,Msp,Timeout]),
+ if
+ Low<Msp, Msp<High -> ok;
+ true -> {fail, "timeout not within limits"}
+ end;
+
+ {done, Client, {error,Other}, _T0} ->
+ ct:log("Error message \"~p\" from the client is unexpected.",[{error,Other}]),
+ {fail, "Unexpected error message"};
+
+ {done, Client, {ok,_Ref}, _T0} ->
+ {fail,"ssh-connected ???"}
+ after
+ 5000 ->
+ exit(Server,hasta_la_vista___baby),
+ exit(Client,hasta_la_vista___baby),
+ {fail, "Didn't timeout"}
+ end.
+
+%% Help function, elapsed milliseconds since T0
+ms_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) / 1000.
+
+%%--------------------------------------------------------------------
+ssh_daemon_minimal_remote_max_packet_size_option(Config) ->
+ SystemDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+
+ {Server, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"vego", "morot"}]},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {minimal_remote_max_packet_size, 14}]),
+ Conn =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {user, "vego"},
+ {password, "morot"}]),
+
+ %% Try the limits of the minimal_remote_max_packet_size:
+ {ok, _ChannelId} = ssh_connection:session_channel(Conn, 100, 14, infinity),
+ {open_error,_,"Maximum packet size below 14 not supported",_} =
+ ssh_connection:session_channel(Conn, 100, 13, infinity),
+
+ ssh:close(Conn),
+ ssh:stop_daemon(Server).
+
+%%--------------------------------------------------------------------
+%% This test try every algorithm by connecting to an Erlang server
+id_string_no_opt_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [], 1000),
+ receive
+ {id,Server,"SSH-2.0-Erlang/"++Vsn} ->
+ true = expected_ssh_vsn(Vsn);
+ {id,Server,Other} ->
+ ct:fail("Unexpected id: ~s.",[Other])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_own_string_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [{id_string,"Pelle"}], 1000),
+ receive
+ {id,Server,"SSH-2.0-Pelle\r\n"} ->
+ ok;
+ {id,Server,Other} ->
+ ct:fail("Unexpected id: ~s.",[Other])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_random_client(Config) ->
+ {Server, _Host, Port} = fake_daemon(Config),
+ {error,_} = ssh:connect("localhost", Port, [{id_string,random}], 1000),
+ receive
+ {id,Server,Id="SSH-2.0-Erlang"++_} ->
+ ct:fail("Unexpected id: ~s.",[Id]);
+ {id,Server,Rnd="SSH-2.0-"++_} ->
+ ct:log("Got correct ~s",[Rnd]);
+ {id,Server,Id} ->
+ ct:fail("Unexpected id: ~s.",[Id])
+ after 5000 ->
+ {fail,timeout}
+ end.
+
+%%--------------------------------------------------------------------
+id_string_no_opt_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, []),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-Erlang/"++Vsn} = gen_tcp:recv(S1, 0, 2000),
+ true = expected_ssh_vsn(Vsn).
+
+%%--------------------------------------------------------------------
+id_string_own_string_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,"Olle"}]),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-Olle\r\n"} = gen_tcp:recv(S1, 0, 2000).
+
+%%--------------------------------------------------------------------
+id_string_random_server(Config) ->
+ {_Server, Host, Port} = ssh_test_lib:std_daemon(Config, [{id_string,random}]),
+ {ok,S1}=gen_tcp:connect(Host,Port,[{active,false},{packet,line}]),
+ {ok,"SSH-2.0-"++Rnd} = gen_tcp:recv(S1, 0, 2000),
+ case Rnd of
+ "Erlang"++_ -> ct:log("Id=~p",[Rnd]),
+ {fail,got_default_id};
+ "Olle\r\n" -> {fail,got_previous_tests_value};
+ _ -> ct:log("Got ~s.",[Rnd])
+ end.
+
+%%--------------------------------------------------------------------
+ssh_connect_negtimeout_parallel(Config) -> ssh_connect_negtimeout(Config,true).
+ssh_connect_negtimeout_sequential(Config) -> ssh_connect_negtimeout(Config,false).
+
+ssh_connect_negtimeout(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 2000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+
+ {ok,Socket} = gen_tcp:connect(Host, Port, []),
+
+ Factor = 2,
+ ct:log("And now sleeping ~p*NegTimeOut (~p ms)...", [Factor, round(Factor * NegTimeOut)]),
+ ct:sleep(round(Factor * NegTimeOut)),
+
+ case inet:sockname(Socket) of
+ {ok,_} -> ct:fail("Socket not closed");
+ {error,_} -> ok
+ end.
+
+%%--------------------------------------------------------------------
+%%% Test that ssh connection does not timeout if the connection is established (parallel)
+ssh_connect_nonegtimeout_connected_parallel(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, true).
+
+%%% Test that ssh connection does not timeout if the connection is established (non-parallel)
+ssh_connect_nonegtimeout_connected_sequential(Config) ->
+ ssh_connect_nonegtimeout_connected(Config, false).
+
+
+ssh_connect_nonegtimeout_connected(Config, Parallel) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ NegTimeOut = 20000, % ms
+ ct:log("Parallel: ~p",[Parallel]),
+
+ {_Pid, _Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},{user_dir, UserDir},
+ {parallel_login, Parallel},
+ {negotiation_timeout, NegTimeOut},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ct:log("~p Listen ~p:~p",[_Pid,_Host,Port]),
+ ct:sleep(500),
+
+ IO = ssh_test_lib:start_io_server(),
+ Shell = ssh_test_lib:start_shell(Port, IO, UserDir),
+ receive
+ Error = {'EXIT', _, _} ->
+ ct:log("~p",[Error]),
+ ct:fail(no_ssh_connection);
+ ErlShellStart ->
+ ct:log("---Erlang shell start: ~p~n", [ErlShellStart]),
+ one_shell_op(IO, NegTimeOut),
+ one_shell_op(IO, NegTimeOut),
+
+ Factor = 2,
+ ct:log("And now sleeping ~p*NegTimeOut (~p ms)...", [Factor, round(Factor * NegTimeOut)]),
+ ct:sleep(round(Factor * NegTimeOut)),
+
+ one_shell_op(IO, NegTimeOut)
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end,
+ exit(Shell, kill).
+
+
+one_shell_op(IO, TimeOut) ->
+ ct:log("One shell op: Waiting for prompter"),
+ receive
+ ErlPrompt0 -> ct:log("Erlang prompt: ~p~n", [ErlPrompt0])
+ after TimeOut -> ct:fail("Timeout waiting for promter")
+ end,
+
+ IO ! {input, self(), "2*3*7.\r\n"},
+ receive
+ Echo0 -> ct:log("Echo: ~p ~n", [Echo0])
+ after TimeOut -> ct:fail("Timeout waiting for echo")
+ end,
+
+ receive
+ ?NEWLINE -> ct:log("NEWLINE received", [])
+ after TimeOut ->
+ receive Any1 -> ct:log("Bad NEWLINE: ~p",[Any1])
+ after 0 -> ct:fail("Timeout waiting for NEWLINE")
+ end
+ end,
+
+ receive
+ Result0 -> ct:log("Result: ~p~n", [Result0])
+ after TimeOut -> ct:fail("Timeout waiting for result")
+ end.
+
+%%--------------------------------------------------------------------
+max_sessions_ssh_connect_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh__connect,Config)).
+max_sessions_ssh_connect_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh__connect,Config)).
+
+max_sessions_sftp_start_channel_parallel(Config) ->
+ max_sessions(Config, true, connect_fun(ssh_sftp__start_channel, Config)).
+max_sessions_sftp_start_channel_sequential(Config) ->
+ max_sessions(Config, false, connect_fun(ssh_sftp__start_channel, Config)).
+
+
+%%%---- helpers:
+connect_fun(ssh__connect, Config) ->
+ fun(Host,Port) ->
+ ssh_test_lib:connect(Host, Port,
+ [{silently_accept_hosts, true},
+ {user_dir, ?config(priv_dir,Config)},
+ {user_interaction, false},
+ {user, "carni"},
+ {password, "meat"}
+ ])
+ %% ssh_test_lib returns R when ssh:connect returns {ok,R}
+ end;
+connect_fun(ssh_sftp__start_channel, _Config) ->
+ fun(Host,Port) ->
+ {ok,_Pid,ConnRef} =
+ ssh_sftp:start_channel(Host, Port,
+ [{silently_accept_hosts, true},
+ {user, "carni"},
+ {password, "meat"}
+ ]),
+ ConnRef
+ end.
+
+
+max_sessions(Config, ParallelLogin, Connect0) when is_function(Connect0,2) ->
+ Connect = fun(Host,Port) ->
+ R = Connect0(Host,Port),
+ ct:log("Connect(~p,~p) -> ~p",[Host,Port,R]),
+ R
+ end,
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+ MaxSessions = 5,
+ {Pid, Host, Port} = ssh_test_lib:daemon([
+ {system_dir, SystemDir},
+ {user_dir, UserDir},
+ {user_passwords, [{"carni", "meat"}]},
+ {parallel_login, ParallelLogin},
+ {max_sessions, MaxSessions}
+ ]),
+ ct:log("~p Listen ~p:~p for max ~p sessions",[Pid,Host,Port,MaxSessions]),
+ try [Connect(Host,Port) || _ <- lists:seq(1,MaxSessions)]
+ of
+ Connections ->
+ %% Step 1 ok: could set up max_sessions connections
+ ct:log("Connections up: ~p",[Connections]),
+ [_|_] = Connections,
+
+ %% Now try one more than alowed:
+ ct:log("Info Report might come here...",[]),
+ try Connect(Host,Port)
+ of
+ _ConnectionRef1 ->
+ ssh:stop_daemon(Pid),
+ {fail,"Too many connections accepted"}
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ %% Step 2 ok: could not set up max_sessions+1 connections
+ %% This is expected
+ %% Now stop one connection and try to open one more
+ ok = ssh:close(hd(Connections)),
+ receive after 250 -> ok end, % sleep so the supervisor has time to count down. Not nice...
+ try Connect(Host,Port)
+ of
+ _ConnectionRef1 ->
+ %% Step 3 ok: could set up one more connection after killing one
+ %% Thats good.
+ ssh:stop_daemon(Pid),
+ ok
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ %% Bad indeed. Could not set up one more connection even after killing
+ %% one existing. Very bad.
+ ssh:stop_daemon(Pid),
+ {fail,"Does not decrease # active sessions"}
+ end
+ end
+ catch
+ error:{badmatch,{error,"Connection closed"}} ->
+ ssh:stop_daemon(Pid),
+ {fail,"Too few connections accepted"}
+ end.
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+
+expected_ssh_vsn(Str) ->
+ try
+ {ok,L} = application:get_all_key(ssh),
+ proplists:get_value(vsn,L,"")++"\r\n"
+ of
+ Str -> true;
+ "\r\n" -> true;
+ _ -> false
+ catch
+ _:_ -> true %% ssh not started so we dont't know
+ end.
+
+
+fake_daemon(_Config) ->
+ Parent = self(),
+ %% start the server
+ Server = spawn(fun() ->
+ {ok,Sl} = gen_tcp:listen(0,[{packet,line}]),
+ {ok,{Host,Port}} = inet:sockname(Sl),
+ ct:log("fake_daemon listening on ~p:~p~n",[Host,Port]),
+ Parent ! {sockname,self(),Host,Port},
+ Rsa = gen_tcp:accept(Sl),
+ ct:log("Server gen_tcp:accept got ~p",[Rsa]),
+ {ok,S} = Rsa,
+ receive
+ {tcp, S, Id} -> Parent ! {id,self(),Id}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end
+ end),
+ %% Get listening host and port
+ receive
+ {sockname,Server,ServerHost,ServerPort} -> {Server, ServerHost, ServerPort}
+ after
+ 10000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_dsa b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/id_rsa b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_options_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_peername_sockname_server.erl b/lib/ssh/test/ssh_peername_sockname_server.erl
index bc505695d3..88c96fe444 100644
--- a/lib/ssh/test/ssh_peername_sockname_server.erl
+++ b/lib/ssh/test/ssh_peername_sockname_server.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/ssh_property_test_SUITE.erl b/lib/ssh/test/ssh_property_test_SUITE.erl
index ffad8ebbb7..2278719f6a 100644
--- a/lib/ssh/test/ssh_property_test_SUITE.erl
+++ b/lib/ssh/test/ssh_property_test_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2004-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
new file mode 100644
index 0000000000..fe197f8672
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -0,0 +1,716 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_protocol_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("kernel/include/inet.hrl").
+-include_lib("ssh/src/ssh.hrl"). % ?UINT32, ?BYTE, #ssh{} ...
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_auth.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(NEWLINE, <<"\r\n">>).
+-define(REKEY_DATA_TMO, 65000).
+
+-define(v(Key, Config), proplists:get_value(Key, Config)).
+-define(v(Key, Config, Default), proplists:get_value(Key, Config, Default)).
+
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [{group,tool_tests},
+ {group,kex},
+ {group,service_requests},
+ {group,authentication},
+ {group,packet_size_error},
+ {group,field_size_error}
+ ].
+
+groups() ->
+ [{tool_tests, [], [lib_works_as_client,
+ lib_works_as_server,
+ lib_match,
+ lib_no_match
+ ]},
+ {packet_size_error, [], [packet_length_too_large,
+ packet_length_too_short]},
+
+ {field_size_error, [], [service_name_length_too_large,
+ service_name_length_too_short]},
+
+ {kex, [], [no_common_alg_server_disconnects,
+ no_common_alg_client_disconnects,
+ gex_client_init_option_groups,
+ gex_server_gex_limit,
+ gex_client_init_option_groups_moduli_file,
+ gex_client_init_option_groups_file,
+ gex_client_old_request_exact,
+ gex_client_old_request_noexact
+ ]},
+ {service_requests, [], [bad_service_name,
+ bad_long_service_name,
+ bad_very_long_service_name,
+ empty_service_name,
+ bad_service_name_then_correct
+ ]},
+ {authentication, [], [client_handles_keyboard_interactive_0_pwds
+ ]}
+ ].
+
+
+init_per_suite(Config) ->
+ start_std_daemon( setup_dirs( start_apps(Config))).
+
+end_per_suite(Config) ->
+ stop_apps(Config).
+
+
+
+init_per_testcase(no_common_alg_server_disconnects, Config) ->
+ start_std_daemon(Config, [{preferred_algorithms,[{public_key,['ssh-rsa']}]}]);
+
+init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ Opts = case TC of
+ gex_client_init_option_groups ->
+ [{dh_gex_groups, [{2345, 3, 41}]}];
+ gex_client_init_option_groups_file ->
+ DataDir = ?config(data_dir, Config),
+ F = filename:join(DataDir, "dh_group_test"),
+ [{dh_gex_groups, {file,F}}];
+ gex_client_init_option_groups_moduli_file ->
+ DataDir = ?config(data_dir, Config),
+ F = filename:join(DataDir, "dh_group_test.moduli"),
+ [{dh_gex_groups, {ssh_moduli_file,F}}];
+ _ when TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ [{dh_gex_groups, [{ 500, 3, 17},
+ {1000, 7, 91},
+ {3000, 5, 61}]},
+ {dh_gex_limits,{500,1500}}
+ ];
+ _ ->
+ []
+ end,
+ start_std_daemon(Config,
+ [{preferred_algorithms, ssh:default_algorithms()}
+ | Opts]);
+init_per_testcase(_TestCase, Config) ->
+ check_std_daemon_works(Config, ?LINE).
+
+end_per_testcase(no_common_alg_server_disconnects, Config) ->
+ stop_std_daemon(Config);
+end_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
+ TC == gex_client_init_option_groups_moduli_file ;
+ TC == gex_client_init_option_groups_file ;
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ stop_std_daemon(Config);
+end_per_testcase(_TestCase, Config) ->
+ check_std_daemon_works(Config, ?LINE).
+
+%%%--------------------------------------------------------------------
+%%% Test Cases --------------------------------------------------------
+%%%--------------------------------------------------------------------
+
+%%%--------------------------------------------------------------------
+%%% Connect to an erlang server and check that the testlib acts as a client.
+lib_works_as_client(Config) ->
+ %% Connect and negotiate keys
+ {ok,InitialState} = ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]}]
+ ),
+ {ok,AfterKexState} = connect_and_kex(Config, InitialState),
+
+ %% Do the authentcation
+ {User,Pwd} = server_user_password(Config),
+ {ok,EndState} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_service_request{name = "ssh-userauth"}},
+ {match, #ssh_msg_service_accept{name = "ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_userauth_request{user = User,
+ service = "ssh-connection",
+ method = "password",
+ data = <<?BOOLEAN(?FALSE),
+ ?STRING(unicode:characters_to_binary(Pwd))>>
+ }},
+ {match, #ssh_msg_userauth_success{_='_'}, receive_msg}
+ ], AfterKexState),
+
+ %% Disconnect
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{send, #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION,
+ description = "End of the fun",
+ language = ""
+ }},
+ close_socket
+ ], EndState).
+
+
+%%--------------------------------------------------------------------
+%%% Connect an erlang client and check that the testlib can act as a server.
+lib_works_as_server(Config) ->
+ {User,_Pwd} = server_user_password(Config),
+
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+
+ %% Start a process handling one connection on the server side:
+ spawn_link(
+ fun() ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_messages]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+
+ {match, #ssh_msg_kexdh_init{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_reply},
+
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg},
+
+ {match, #ssh_msg_service_request{name="ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_service_accept{name="ssh-userauth"}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="none",
+ user=User,
+ _='_'}, receive_msg},
+
+ {send, #ssh_msg_userauth_failure{authentications = "password",
+ partial_success = false}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="password",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_success{}},
+ close_socket,
+ print_state
+ ],
+ InitialState)
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client:
+ {ok,_} = std_connect(HostPort, Config,
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ ).
+
+%%--------------------------------------------------------------------
+%%% Matching
+lib_match(_Config) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec([{set_options, [print_ops]},
+ {match, abc, abc},
+ {match, '$a', {cde,fgh}},
+ {match, {cde,fgh}, '$a'},
+ {match, '_', {cde,fgh}},
+ {match, [a,'$a',b], [a,{cde,fgh},b]},
+ {match, [a,'$a'|'$b'], [a,{cde,fgh},b,c]},
+ {match, '$b', [b,c]}
+ ]).
+
+%%--------------------------------------------------------------------
+%%% Not matching
+lib_no_match(_Config) ->
+ case ssh_trpt_test_lib:exec([{set_options, [print_ops]},
+ {match, '$x', b},
+ {match, a, '$x'}])
+ of
+ {ok,_} -> {fail,"Unexpected match"};
+ {error, {_Op,{expected,a,b},_State}} -> ok
+ end.
+
+%%--------------------------------------------------------------------
+%%% Algo negotiation fail. This should result in a ssh_msg_disconnect
+%%% being sent from the server.
+no_common_alg_server_disconnects(Config) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, {print_messages,detail}]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{public_key,['ssh-dss']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, ssh_msg_kexinit}, % with server unsupported 'ssh-dss' !
+ {match, disconnect(), receive_msg}
+ ]
+ ).
+
+%%--------------------------------------------------------------------
+%%% Algo negotiation fail. This should result in a ssh_msg_disconnect
+%%% being sent from the client.
+no_common_alg_client_disconnects(Config) ->
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+ Parent = self(),
+
+ %% Start a process handling one connection on the server side:
+ Pid =
+ spawn_link(
+ fun() ->
+ Parent !
+ {result,self(),
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, {print_messages,detail}]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kexinit{ % with unsupported "SOME-UNSUPPORTED"
+ cookie = 247381486335508958743193106082599558706,
+ kex_algorithms = ["diffie-hellman-group1-sha1"],
+ server_host_key_algorithms = ["SOME-UNSUPPORTED"], % SIC!
+ encryption_algorithms_client_to_server = ["aes128-ctr"],
+ encryption_algorithms_server_to_client = ["aes128-ctr"],
+ mac_algorithms_client_to_server = ["hmac-sha2-256"],
+ mac_algorithms_server_to_client = ["hmac-sha2-256"],
+ compression_algorithms_client_to_server = ["none"],
+ compression_algorithms_server_to_client = ["none"],
+ languages_client_to_server = [],
+ languages_server_to_client = [],
+ first_kex_packet_follows = false,
+ reserved = 0
+ }},
+ {match, disconnect(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED), receive_msg}
+ ],
+ InitialState)
+ }
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client
+ %% which of course does not support SOME-UNSUPPORTED as pub key algo:
+ Result = std_connect(HostPort, Config, [{preferred_algorithms,[{public_key,['ssh-dss']}]}]),
+ ct:log("Result of connect is ~p",[Result]),
+
+ receive
+ {result,Pid,{ok,_}} ->
+ ok;
+ {result,Pid,{error,{Op,ExecResult,S}}} ->
+ ct:log("ERROR!~nOp = ~p~nExecResult = ~p~nState =~n~s",
+ [Op,ExecResult,ssh_trpt_test_lib:format_msg(S)]),
+ {fail, ExecResult};
+ X ->
+ ct:log("¤¤¤¤¤"),
+ ct:fail(X)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+%%%--------------------------------------------------------------------
+gex_client_init_option_groups(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {3,41}).
+
+gex_client_init_option_groups_file(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {5,61}).
+
+gex_client_init_option_groups_moduli_file(Config) ->
+ do_gex_client_init(Config, {2000, 2048, 4000},
+ {5,16#B7}).
+
+gex_server_gex_limit(Config) ->
+ do_gex_client_init(Config, {1000, 3000, 4000},
+ {7,91}).
+
+
+do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request{min = Min,
+ n = N,
+ max = Max}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
+
+%%%--------------------------------------------------------------------
+gex_client_old_request_exact(Config) -> do_gex_client_init_old(Config, 500, {3,17}).
+gex_client_old_request_noexact(Config) -> do_gex_client_init_old(Config, 800, {7,91}).
+
+do_gex_client_init_old(Config, N, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request_old{n = N}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
+
+%%%--------------------------------------------------------------------
+bad_service_name(Config) ->
+ bad_service_name(Config, "kfglkjf").
+
+bad_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(?SSH_MAX_PACKET_SIZE div 2, $a)).
+
+bad_very_long_service_name(Config) ->
+ bad_service_name(Config,
+ lists:duplicate(4*?SSH_MAX_PACKET_SIZE, $a)).
+
+empty_service_name(Config) ->
+ bad_service_name(Config, "").
+
+bad_service_name_then_correct(Config) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = "kdjglkfdjgkldfjglkdfjglkfdjglkj"}},
+ {send, #ssh_msg_service_request{name = "ssh-connection"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+
+bad_service_name(Config, Name) ->
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, #ssh_msg_service_request{name = Name}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+packet_length_too_large(Config) -> bad_packet_length(Config, +4).
+
+packet_length_too_short(Config) -> bad_packet_length(Config, -4).
+
+bad_packet_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(Msg, Ssh) ->
+ BinMsg = ssh_message:encode(Msg),
+ ssh_transport:pack(BinMsg, Ssh, LengthExcess)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun}},
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+service_name_length_too_large(Config) -> bad_service_name_length(Config, +4).
+
+service_name_length_too_short(Config) -> bad_service_name_length(Config, -4).
+
+
+bad_service_name_length(Config, LengthExcess) ->
+ PacketFun =
+ fun(#ssh_msg_service_request{name=Service}, Ssh) ->
+ BinName = list_to_binary(Service),
+ BinMsg =
+ <<?BYTE(?SSH_MSG_SERVICE_REQUEST),
+ %% A bad string encoding of Service:
+ ?UINT32(size(BinName)+LengthExcess), BinName/binary
+ >>,
+ ssh_transport:pack(BinMsg, Ssh)
+ end,
+ {ok,InitialState} = connect_and_kex(Config),
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {send, {special,
+ #ssh_msg_service_request{name="ssh-userauth"},
+ PacketFun} },
+ %% Prohibit remote decoder starvation:
+ {send, #ssh_msg_service_request{name="ssh-userauth"}},
+ {match, disconnect(), receive_msg}
+ ], InitialState).
+
+%%%--------------------------------------------------------------------
+%%% This is due to a fault report (OTP-13255) with OpenSSH-6.6.1
+client_handles_keyboard_interactive_0_pwds(Config) ->
+ {User,_Pwd} = server_user_password(Config),
+
+ %% Create a listening socket as server socket:
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ HostPort = ssh_trpt_test_lib:server_host_port(InitialState),
+
+ %% Start a process handling one connection on the server side:
+ spawn_link(
+ fun() ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_messages]},
+ {accept, [{system_dir, system_dir(Config)},
+ {user_dir, user_dir(Config)}]},
+ receive_hello,
+ {send, hello},
+
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+
+ {match, #ssh_msg_kexdh_init{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_reply},
+
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg},
+
+ {match, #ssh_msg_service_request{name="ssh-userauth"}, receive_msg},
+ {send, #ssh_msg_service_accept{name="ssh-userauth"}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="none",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_failure{authentications = "keyboard-interactive",
+ partial_success = false}},
+
+ {match, #ssh_msg_userauth_request{service="ssh-connection",
+ method="keyboard-interactive",
+ user=User,
+ _='_'}, receive_msg},
+ {send, #ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 1,
+ data = <<0,0,0,10,80,97,115,115,119,111,114,100,58,32,0>>
+ }},
+ {match, #ssh_msg_userauth_info_response{num_responses = 1,
+ _='_'}, receive_msg},
+
+ %% the next is strange, but openssh 6.6.1 does this and this is what this testcase is about
+ {send, #ssh_msg_userauth_info_request{name = "",
+ instruction = "",
+ language_tag = "",
+ num_prompts = 0,
+ data = <<>>
+ }},
+ {match, #ssh_msg_userauth_info_response{num_responses = 0,
+ data = <<>>,
+ _='_'}, receive_msg},
+ %% Here we know that the tested fault is fixed
+ {send, #ssh_msg_userauth_success{}},
+ close_socket,
+ print_state
+ ],
+ InitialState)
+ end),
+
+ %% and finally connect to it with a regular Erlang SSH client:
+ {ok,_} = std_connect(HostPort, Config,
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]}]
+ ).
+
+
+%%%================================================================
+%%%==== Internal functions ========================================
+%%%================================================================
+
+%%%---- init_suite and end_suite ---------------------------------------
+start_apps(Config) ->
+ catch crypto:stop(),
+ case catch crypto:start() of
+ ok ->
+ catch ssh:stop(),
+ ok = ssh:start(),
+ [{stop_apps,
+ fun() ->
+ ssh:stop(),
+ crypto:stop()
+ end} | Config];
+ _Else ->
+ {skip, "Crypto could not be started!"}
+ end.
+
+
+stop_apps(Config) ->
+ (?v(stop_apps, Config, fun()-> ok end))(),
+ ssh:stop().
+
+
+setup_dirs(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ ssh_test_lib:setup_rsa(DataDir, PrivDir),
+ Config.
+
+system_dir(Config) -> filename:join(?config(priv_dir, Config), system).
+
+user_dir(Config) -> ?config(priv_dir, Config).
+
+%%%----------------------------------------------------------------
+start_std_daemon(Config) ->
+ start_std_daemon(Config, []).
+
+start_std_daemon(Config, ExtraOpts) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ UserPasswords = [{"user1","pwd1"}],
+ Options = [%%{preferred_algorithms,[{public_key,['ssh-rsa']}]}, %% For some test cases
+ {system_dir, system_dir(Config)},
+ {user_dir, UserDir},
+ {user_passwords, UserPasswords},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | ExtraOpts],
+ Ref = {Server, Host, Port} = ssh_test_lib:daemon(Options),
+ ct:log("Std server ~p started at ~p:~p~nOptions=~p",[Server, Host, Port, Options]),
+ [{server,Ref}, {user_passwords, UserPasswords} | Config].
+
+
+stop_std_daemon(Config) ->
+ ssh:stop_daemon(server_pid(Config)),
+ ct:log("Std server ~p at ~p:~p stopped", [server_pid(Config), server_host(Config), server_port(Config)]),
+ lists:keydelete(server, 1, Config).
+
+
+check_std_daemon_works(Config, Line) ->
+ case std_connect(Config) of
+ {ok,C} ->
+ ct:log("Server ~p:~p ~p is ok at line ~p",
+ [server_host(Config), server_port(Config),
+ server_pid(Config), Line]),
+ ok = ssh:close(C),
+ Config;
+ Error = {error,_} ->
+ ct:fail("Standard server ~p:~p ~p is ill at line ~p: ~p",
+ [server_host(Config), server_port(Config),
+ server_pid(Config), Line, Error])
+ end.
+
+server_pid(Config) -> element(1,?v(server,Config)).
+server_host(Config) -> element(2,?v(server,Config)).
+server_port(Config) -> element(3,?v(server,Config)).
+
+server_user_password(Config) -> server_user_password(1, Config).
+
+server_user_password(N, Config) -> lists:nth(N, ?v(user_passwords,Config)).
+
+
+std_connect(Config) ->
+ std_connect({server_host(Config), server_port(Config)}, Config).
+
+std_connect({Host,Port}, Config) ->
+ std_connect({Host,Port}, Config, []).
+
+std_connect({Host,Port}, Config, Opts) ->
+ std_connect(Host, Port, Config, Opts).
+
+std_connect(Host, Port, Config, Opts) ->
+ {User,Pwd} = server_user_password(Config),
+ ssh:connect(Host, Port,
+ %% Prefere User's Opts to the default opts
+ [O || O = {Tag,_} <- [{user,User},{password,Pwd},
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false}],
+ not lists:keymember(Tag, 1, Opts)
+ ] ++ Opts,
+ 30000).
+
+%%%----------------------------------------------------------------
+connect_and_kex(Config) ->
+ connect_and_kex(Config, ssh_trpt_test_lib:exec([]) ).
+
+connect_and_kex(Config, InitialState) ->
+ ssh_trpt_test_lib:exec(
+ [{connect,
+ server_host(Config),server_port(Config),
+ [{preferred_algorithms,[{kex,['diffie-hellman-group1-sha1']}]},
+ {silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false}]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, ssh_msg_kexdh_init},
+ {match,# ssh_msg_kexdh_reply{_='_'}, receive_msg},
+ {send, #ssh_msg_newkeys{}},
+ {match, #ssh_msg_newkeys{_='_'}, receive_msg}
+ ],
+ InitialState).
+
+%%%----------------------------------------------------------------
+
+%%% For matching peer disconnection
+disconnect() ->
+ disconnect('_').
+
+disconnect(Code) ->
+ {'or',[#ssh_msg_disconnect{code = Code,
+ _='_'},
+ tcp_closed,
+ {tcp_error,econnaborted}
+ ]}.
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
new file mode 100644
index 0000000000..2887bb4b60
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test
@@ -0,0 +1,3 @@
+{2222, 5, 61}.
+{1111, 7, 91}.
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
new file mode 100644
index 0000000000..f6995ba4c9
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/dh_group_test.moduli
@@ -0,0 +1,3 @@
+20151021104105 2 6 100 2222 5 B7
+20151021104106 2 6 100 1111 5 4F
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_protocol_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_relay.erl b/lib/ssh/test/ssh_relay.erl
new file mode 100644
index 0000000000..28000fbb97
--- /dev/null
+++ b/lib/ssh/test/ssh_relay.erl
@@ -0,0 +1,407 @@
+%%%-------------------------------------------------------------------
+%%% @author Simon Cornish <[email protected]>
+%%% @copyright (C) 2015, Simon Cornish
+%%% @doc
+%%% Provide manipulatable TCP-level relaying for testing SSH
+%%% @end
+%%% Created : 7 May 2015 by Simon Cornish <[email protected]>
+%%%-------------------------------------------------------------------
+-module(ssh_relay).
+
+-behaviour(gen_server).
+
+%% API
+-export([start_link/4]).
+-export([stop/1]).
+-export([hold/4, release/2, release_next/3]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-record(hold, {
+ port,
+ n,
+ tmo,
+ tref,
+ q = []
+ }).
+
+-record(state, {
+ local_addr,
+ local_port,
+ peer_addr,
+ peer_port,
+ lpid,
+ local,
+ peer,
+ tx_hold,
+ rx_hold
+ }).
+
+-define(ACCEPT_TMO, 200).
+%%%===================================================================
+%%% API
+%%%===================================================================
+%%--------------------------------------------------------------------
+%% @doc
+%% Hold N (or 'all') messages in given direction.
+%% Messages will be released after the N+1th message or
+%% Tmo ms or 'infinity'
+%%
+%% Dir is 'tx' for direction local -> peer
+%% and 'rx' for direction peer -> local
+%%
+%% An Error, ealready, is returned if there is already a hold
+%% in the given direction
+%%
+%% @spec hold(Srv, Dir, N, Tmo) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+hold(Srv, Dir, N, Tmo) ->
+ gen_server:call(Srv, {hold, Dir, N, Tmo}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Release all held messages in given direction.
+%%
+%% An Error, enoent, is returned if there is no hold
+%% in the given direction
+%%
+%% @spec release(Srv, Dir) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+release(Srv, Dir) ->
+ gen_server:call(Srv, {release, Dir}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Release all held messages in given direction after the
+%% next message in the trigger direction
+%%
+%% An Error, enoent, is returned if there is no hold
+%% in the given direction
+%%
+%% @spec release_next(Srv, Dir, TriggerDir) -> ok | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+release_next(Srv, Dir, TriggerDir) ->
+ gen_server:call(Srv, {release_next, Dir, TriggerDir}).
+
+%%--------------------------------------------------------------------
+%% @doc
+%% Starts the server
+%%
+%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
+%% @end
+%%--------------------------------------------------------------------
+start_link(ListenAddr, ListenPort, PeerAddr, PeerPort) ->
+ gen_server:start_link(?MODULE, [ListenAddr, ListenPort, PeerAddr, PeerPort], []).
+
+stop(Srv) ->
+ unlink(Srv),
+ Srv ! stop.
+
+%%%===================================================================
+%%% gen_server callbacks
+%%%===================================================================
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Initializes the server
+%%
+%% @spec init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% @end
+%%--------------------------------------------------------------------
+init([ListenAddr, ListenPort, PeerAddr, PeerPort | _Options]) ->
+ IfAddr = case ListenAddr of
+ {0,0,0,0} ->
+ [];
+ _ ->
+ [{ifaddr, ListenAddr}]
+ end,
+ case gen_tcp:listen(ListenPort, [{reuseaddr, true}, {backlog, 1}, {active, false}, binary | IfAddr]) of
+ {ok, LSock} ->
+ Parent = self(),
+ {LPid, _LMod} = spawn_monitor(fun() -> listen(Parent, LSock) end),
+ S = #state{local_addr = ListenAddr,
+ local_port = ListenPort,
+ lpid = LPid,
+ peer_addr = PeerAddr,
+ peer_port = PeerPort
+ },
+ {ok, S};
+ Error ->
+ {stop, Error}
+ end.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling call messages
+%%
+%% @spec handle_call(Request, From, State) ->
+%% {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_call({hold, Dir, N, Tmo}, _From, State) ->
+ case Dir of
+ tx ->
+ do_hold(#state.tx_hold, State#state.peer, N, Tmo, State);
+ rx ->
+ do_hold(#state.rx_hold, State#state.local, N, Tmo, State);
+ _ ->
+ {reply, {error, einval}, State}
+ end;
+handle_call({release, Dir}, _From, State) ->
+ case Dir of
+ tx ->
+ do_release(#state.tx_hold, State);
+ rx ->
+ do_release(#state.rx_hold, State);
+ _ ->
+ {reply, {error, einval}, State}
+ end;
+handle_call({release_next, _Dir, _TriggerDir}, _From, State) ->
+ {reply, {error, nyi}, State};
+
+handle_call(Request, _From, State) ->
+ Reply = {unhandled, Request},
+ {reply, Reply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling cast messages
+%%
+%% @spec handle_cast(Msg, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Handling all non call/cast messages
+%%
+%% @spec handle_info(Info, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @end
+%%--------------------------------------------------------------------
+handle_info({tcp, Local, Data}, S) when S#state.local == Local ->
+ S1 = do_local(Data, S),
+ {noreply, S1};
+
+handle_info({tcp_error, Local, Error}, S) when S#state.local == Local ->
+ S1 = do_local({error, Error}, S),
+ {noreply, S1};
+
+handle_info({tcp_closed, Local}, S) when S#state.local == Local ->
+ S1 = do_local(closed, S),
+ {noreply, S1};
+
+handle_info({tcp, Peer, Data}, S) when S#state.peer == Peer ->
+ S1 = do_peer(Data, S),
+ {noreply, S1};
+
+handle_info({tcp_error, Peer, Error}, S) when S#state.peer == Peer ->
+ S1 = do_peer({error, Error}, S),
+ {noreply, S1};
+
+handle_info({tcp_closed, Peer}, S) when S#state.peer == Peer ->
+ S1 = do_peer(closed, S),
+ {noreply, S1};
+
+handle_info({accept, Local}, S) ->
+ S1 = do_accept(Local, S),
+ {noreply, S1};
+
+handle_info({activate, Local}, State) ->
+ inet:setopts(Local, [{active, true}]),
+ {noreply, State};
+
+handle_info({release, Pos}, S) ->
+ {reply, _, S1} = do_release(Pos,S),
+ {noreply, S1};
+
+handle_info(stop, State) ->
+ {stop, normal, State};
+
+handle_info({'DOWN', _Ref, _process, LPid, Reason}, S) when S#state.lpid == LPid ->
+ io:format("Acceptor has finished: ~p~n", [Reason]),
+ {noreply, S};
+
+handle_info(_Info, State) ->
+ io:format("Unhandled info: ~p~n", [_Info]),
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% This function is called by a gen_server when it is about to
+%% terminate. It should be the opposite of Module:init/1 and do any
+%% necessary cleaning up. When it returns, the gen_server terminates
+%% with Reason. The return value is ignored.
+%%
+%% @spec terminate(Reason, State) -> void()
+%% @end
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @private
+%% @doc
+%% Convert process state when code is changed
+%%
+%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% @end
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+do_hold(Pos, _Port, _N, _Tmo, S) when element(Pos, S) /= undefined ->
+ {reply, {error, ealready}, S};
+do_hold(Pos, Port, N, Tmo, S) ->
+ TRef = if is_integer(Tmo) andalso Tmo > 0 ->
+ erlang:send_after(Tmo, self(), {release, Pos});
+ true ->
+ undefined
+ end,
+ Hold = #hold{port = Port, n = N, tmo = Tmo, tref = TRef},
+ {reply, ok, setelement(Pos, S, Hold)}.
+
+do_release(HPos, S) when element(HPos, S) == undefined ->
+ {reply, {error, enoent}, S};
+do_release(HPos, S) ->
+ #hold{port = Port, tref = TRef, q = Q} = element(HPos, S),
+ lists:foreach(fun(M) -> gen_tcp:send(Port, M), erlang:yield() end, Q),
+ catch erlang:cancel_timer(TRef),
+ receive
+ {release, HPos} -> ok
+ after 0 ->
+ ok
+ end,
+ {reply, ok, setelement(HPos, S, undefined)}.
+
+listen(Parent, LSock) ->
+ monitor(process, Parent),
+ do_listen(Parent, LSock).
+
+do_listen(Parent, LSock) ->
+ %% So annoying there is no select-like sematic for this
+ case gen_tcp:accept(LSock, ?ACCEPT_TMO) of
+ {ok, Sock} ->
+ Parent ! {accept, Sock},
+ gen_tcp:controlling_process(Sock, Parent),
+ Parent ! {activate, Sock},
+ do_flush(Parent, Sock),
+ gen_tcp:close(LSock);
+ {error, timeout} ->
+ receive
+ DOWN when element(1, DOWN) == 'DOWN' ->
+ ok;
+ stop ->
+ ok
+ after 1 ->
+ do_listen(Parent, LSock)
+ end;
+ Error ->
+ gen_tcp:close(LSock),
+ exit({accept,Error})
+ end.
+
+do_flush(Parent, Sock) ->
+ receive
+ {Tcp, Sock, _} = Msg when Tcp == tcp; Tcp == tcp_error ->
+ Parent ! Msg,
+ do_flush(Parent, Sock);
+ {tcp_closed, Sock} = Msg ->
+ Parent ! Msg,
+ do_flush(Parent, Sock)
+ after 1 ->
+ ok
+ end.
+
+do_accept(Local, S) ->
+ case gen_tcp:connect(S#state.peer_addr, S#state.peer_port, [{active, true}, binary]) of
+ {ok, Peer} ->
+ S#state{local = Local, peer = Peer};
+ Error ->
+ exit({connect, Error})
+ end.
+
+do_local(Data, S) when is_binary(Data) ->
+ TxH = S#state.tx_hold,
+ if TxH == undefined ->
+ gen_tcp:send(S#state.peer, Data),
+ S;
+ TxH#hold.n == 0 ->
+ lists:foreach(fun(M) -> gen_tcp:send(S#state.peer, M) end, TxH#hold.q),
+ gen_tcp:send(S#state.peer, Data),
+ catch erlang:cancel_timer(TxH#hold.tref),
+ TxP = #state.tx_hold,
+ receive
+ {release, TxP} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ S#state{tx_hold = undefined};
+ true ->
+ Q = TxH#hold.q ++ [Data],
+ N = if is_integer(TxH#hold.n) ->
+ TxH#hold.n -1;
+ true ->
+ TxH#hold.n
+ end,
+ S#state{tx_hold = TxH#hold{q = Q, n = N}}
+ end;
+do_local(Error, _S) ->
+ exit({local, Error}).
+
+do_peer(Data, S) when is_binary(Data) ->
+ RxH = S#state.rx_hold,
+ if RxH == undefined ->
+ gen_tcp:send(S#state.local, Data),
+ S;
+ RxH#hold.n == 0 ->
+ lists:foreach(fun(M) -> gen_tcp:send(S#state.local, M) end, RxH#hold.q),
+ gen_tcp:send(S#state.local, Data),
+ catch erlang:cancel_timer(RxH#hold.tref),
+ RxP = #state.rx_hold,
+ receive
+ {release, RxP} ->
+ ok
+ after 0 ->
+ ok
+ end,
+ S#state{rx_hold = undefined};
+ true ->
+ Q = RxH#hold.q ++ [Data],
+ N = if is_integer(RxH#hold.n) ->
+ RxH#hold.n -1;
+ true ->
+ RxH#hold.n
+ end,
+ S#state{rx_hold = RxH#hold{q = Q, n = N}}
+ end;
+do_peer(Error, _S) ->
+ exit({peer, Error}).
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE.erl b/lib/ssh/test/ssh_renegotiate_SUITE.erl
new file mode 100644
index 0000000000..e5cfa58bad
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE.erl
@@ -0,0 +1,254 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ssh_renegotiate_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(REKEY_DATA_TMO, 65000).
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() -> [{group,default_algs},
+ {group,aes_gcm}
+ ].
+
+groups() -> [{default_algs, [], tests()},
+ {aes_gcm, [], tests()}
+ ].
+
+tests() -> [rekey, rekey_limit, renegotiate1, renegotiate2].
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ catch crypto:stop(),
+ case catch crypto:start() of
+ ok ->
+ Config;
+ _Else ->
+ {skip, "Crypto could not be started!"}
+ end.
+end_per_suite(_Config) ->
+ ssh:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+init_per_group(aes_gcm, Config) ->
+ case lists:member({client2server,['[email protected]']},
+ ssh_transport:supported_algorithms(cipher)) of
+ true ->
+ [{preferred_algorithms, [{cipher,[{client2server,['[email protected]']},
+ {server2client,['[email protected]']}]}]}
+ | Config];
+ false ->
+ {skip, "aes_gcm not supported"}
+ end;
+init_per_group(_, Config) ->
+ [{preferred_algorithms, ssh:default_algorithms()} | Config].
+
+
+end_per_group(_, Config) ->
+ Config.
+
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config) ->
+ ssh:start(),
+ Config.
+
+end_per_testcase(_TestCase, _Config) ->
+ ssh:stop(),
+ ok.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%%% Idle timeout test
+
+rekey(Config) ->
+ {Pid, Host, Port} =
+ ssh_test_lib:std_daemon(Config,
+ [{rekey_limit, 0}]),
+ ConnectionRef =
+ ssh_test_lib:std_connect(Config, Host, Port,
+ [{rekey_limit, 0}]),
+ Kex1 = get_kex_init(ConnectionRef),
+ receive
+ after ?REKEY_DATA_TMO ->
+ %%By this time rekeying would have been done
+ Kex2 = get_kex_init(ConnectionRef),
+ false = (Kex2 == Kex1),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid)
+ end.
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying by data volume
+
+rekey_limit(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "rekey.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, [{rekey_limit, 6000},
+ {max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = get_kex_init(ConnectionRef),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex1 = get_kex_init(ConnectionRef),
+
+ Data = lists:duplicate(159000,1),
+ ok = ssh_sftp:write_file(SftpPid, DataFile, Data),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ ok = ssh_sftp:write_file(SftpPid, DataFile, "hi\n"),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ timer:sleep(?REKEY_DATA_TMO),
+ Kex2 = get_kex_init(ConnectionRef),
+
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with simulataneous send request
+
+renegotiate1(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate1.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ RPort = ssh_test_lib:inet_port(),
+ {ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
+
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = get_kex_init(ConnectionRef),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, 1000),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+
+ timer:sleep(2000),
+
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+
+%%% Test rekeying with inflight messages from peer
+
+renegotiate2(Config) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "renegotiate2.data"),
+
+ Algs = ?config(preferred_algorithms, Config),
+ {Pid, Host, DPort} = ssh_test_lib:std_daemon(Config,[{max_random_length_padding,0},
+ {preferred_algorithms,Algs}]),
+
+ RPort = ssh_test_lib:inet_port(),
+ {ok,RelayPid} = ssh_relay:start_link({0,0,0,0}, RPort, Host, DPort),
+
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, RPort, [{max_random_length_padding,0}]),
+ {ok, SftpPid} = ssh_sftp:start_channel(ConnectionRef),
+
+ Kex1 = get_kex_init(ConnectionRef),
+
+ {ok, Handle} = ssh_sftp:open(SftpPid, DataFile, [write]),
+
+ ok = ssh_sftp:write(SftpPid, Handle, "hi\n"),
+
+ ssh_relay:hold(RelayPid, rx, 20, infinity),
+ spawn(fun() -> ok=ssh_sftp:write(SftpPid, Handle, "another hi\n") end),
+ %% need a small pause here to ensure ssh_sftp:write is executed
+ ct:sleep(10),
+ ssh_connection_handler:renegotiate(ConnectionRef),
+ ssh_relay:release(RelayPid, rx),
+
+ timer:sleep(2000),
+
+ Kex2 = get_kex_init(ConnectionRef),
+
+ false = (Kex2 == Kex1),
+
+ ssh_relay:stop(RelayPid),
+ ssh_sftp:stop_channel(SftpPid),
+ ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
+%%--------------------------------------------------------------------
+%% Internal functions ------------------------------------------------
+%%--------------------------------------------------------------------
+%% get_kex_init - helper function to get key_exchange_init_msg
+get_kex_init(Conn) ->
+ %% First, validate the key exchange is complete (StateName == connected)
+ {connected,S} = sys:get_state(Conn),
+ %% Next, walk through the elements of the #state record looking
+ %% for the #ssh_msg_kexinit record. This method is robust against
+ %% changes to either record. The KEXINIT message contains a cookie
+ %% unique to each invocation of the key exchange procedure (RFC4253)
+ SL = tuple_to_list(S),
+ case lists:keyfind(ssh_msg_kexinit, 1, SL) of
+ false ->
+ throw(not_found);
+ KexInit ->
+ KexInit
+ end.
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_renegotiate_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index cb74a27638..698af259c8 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -26,14 +27,9 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-% Default timetrap timeout
+ % Default timetrap timeout
-define(default_timeout, ?t:minutes(1)).
--define(USER, "Alladin").
--define(PASSWD, "Sesame").
-
--define(tar_file_name, "sftp_tar_test.tar").
-
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
@@ -42,15 +38,17 @@ suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, erlang_server},
- {group, openssh_server},
- sftp_nonexistent_subsystem
+ [{group, not_unicode},
+ {group, unicode}
].
init_per_suite(Config) ->
+ catch crypto:stop(),
case (catch crypto:start()) of
ok ->
+ ct:log("file:native_name_encoding() = ~p,~nio:getopts() = ~p",
+ [file:native_name_encoding(),io:getopts()]),
ssh:start(),
Config;
_ ->
@@ -64,61 +62,137 @@ end_per_suite(Config) ->
%%--------------------------------------------------------------------
groups() ->
- [{erlang_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, write_big_file, sftp_read_big_file,
- rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write, version_option,
+ [{not_unicode, [], [{group,erlang_server},
+ {group,openssh_server},
+ sftp_nonexistent_subsystem]},
+
+ {unicode, [], [{group,erlang_server},
+ {group,openssh_server},
+ sftp_nonexistent_subsystem]},
+
+ {erlang_server, [], [{group,write_read_tests},
+ version_option,
{group,remote_tar}]},
- {openssh_server, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, write_big_file, sftp_read_big_file,
- rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read,
- async_write, position, pos_read, pos_write,
+ {openssh_server, [], [{group,write_read_tests},
{group,remote_tar}]},
- {remote_tar, [], [create_empty_tar, files_to_tar, big_file_to_tar, files_chunked_to_tar,
+ {remote_tar, [], [create_empty_tar,
+ ascii_filename_ascii_contents_to_tar,
+ ascii_filename_unicode_contents_to_tar,
+ unicode_filename_ascii_contents_to_tar,
+ files_to_tar,
+ big_file_to_tar, files_chunked_to_tar,
directory_to_tar, binaries_to_tar, null_crypto_tar,
simple_crypto_tar_small, simple_crypto_tar_big,
read_tar, read_null_crypto_tar, read_crypto_tar,
aes_cbc256_crypto_tar, aes_ctr_stream_crypto_tar
- ]}
+ ]},
+
+ {write_read_tests, [], [open_close_file, open_close_dir, read_file, read_dir,
+ write_file, write_file_iolist, write_big_file, sftp_read_big_file,
+ rename_file, mk_rm_dir, remove_file, links,
+ retrieve_attributes, set_attributes, async_read,
+ async_write, position, pos_read, pos_write
+ ]}
].
-
+
+init_per_group(not_unicode, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ [{user, "Alladin"},
+ {passwd, "Sesame"},
+ {data, <<"Hello world!">>},
+ {filename, filename:join(PrivDir, "sftp.txt")},
+ {testfile, filename:join(PrivDir, "test.txt")},
+ {linktest, filename:join(PrivDir, "link_test.txt")},
+ {tar_filename, filename:join(PrivDir, "sftp_tar_test.tar")},
+ {tar_F1_txt, "f1.txt"},
+ {datadir_tar, filename:join(DataDir,"sftp_tar_test_data")}
+ | Config];
+
+init_per_group(unicode, Config) ->
+ case file:native_name_encoding() of
+ utf8 ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ NewConfig =
+ [{user, "åke高兴"},
+ {passwd, "ärlig日本じん"},
+ {data, <<"foobar å 一二三四いちにさんち">>},
+ {filename, filename:join(PrivDir, "sftp瑞点.txt")},
+ {testfile, filename:join(PrivDir, "testハンス.txt")},
+ {linktest, filename:join(PrivDir, "link_test語.txt")},
+ {tar_filename, filename:join(PrivDir, "sftp_tar_test一二三.tar")},
+ {tar_F1_txt, "F一.txt"},
+ {tar_F3_txt, "f3.txt"},
+ {tar_F4_txt, "g四.txt"},
+ {datadir_tar, filename:join(DataDir,"sftp_tar_test_data_高兴")}
+ | lists:foldl(fun(K,Cf) -> lists:keydelete(K,1,Cf) end,
+ Config,
+ [user, passwd, data,
+ filename, testfile, linktest,
+ tar_filename, tar_F1_txt, datadir_tar
+ ]
+ )
+ ],
+ FN = fn(?config(tar_F1_txt,NewConfig), NewConfig),
+ case catch file:read_file(FN) of
+ {ok,FN_contents} ->
+ ct:log("Readable file:read_file(~tp) ->~n~tp",[FN,FN_contents]),
+ NewConfig;
+ Other ->
+ ct:log("Unreadable file:read_file(~tp) ->~n~p",[FN,Other]),
+ {skip, "Not unicode file reading"}
+ end;
+
+ _ ->
+ {skip, "Not unicode file encoding"}
+ end;
init_per_group(erlang_server, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
PrivDir = ?config(priv_dir, Config),
SysDir = ?config(data_dir, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
Sftpd = {_, HostX, PortX} =
ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{user_passwords,
- [{?USER, ?PASSWD}]}]),
+ [{User, Passwd}]}]),
[{peer, {fmt_host(HostX),PortX}}, {group, erlang_server}, {sftpd, Sftpd} | Config];
init_per_group(openssh_server, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
Host = ssh_test_lib:hostname(),
- case (catch ssh_sftp:start_channel(Host,
+ case (catch ssh_sftp:start_channel(Host,
[{user_interaction, false},
{silently_accept_hosts, true}])) of
{ok, _ChannelPid, Connection} ->
[{peer, {_HostName,{IPx,Portx}}}] = ssh:connection_info(Connection,[peer]),
ssh:close(Connection),
[{peer, {fmt_host(IPx),Portx}}, {group, openssh_server} | Config];
+ {error,"Key exchange failed"} ->
+ {skip, "openssh server doesn't support the tested kex algorithm"};
_ ->
{skip, "No openssh server"}
end;
init_per_group(remote_tar, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
{Host,Port} = ?config(peer, Config),
ct:log("Server (~p) at ~p:~p",[?config(group,Config),Host,Port]),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{ok, Connection} =
case ?config(group, Config) of
erlang_server ->
ssh:connect(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
+ [{user, User},
+ {password, Passwd},
{user_interaction, false},
{silently_accept_hosts, true}]);
openssh_server ->
@@ -127,11 +201,23 @@ init_per_group(remote_tar, Config) ->
{silently_accept_hosts, true}])
end,
[{remote_tar, true},
- {connection, Connection} | Config].
+ {connection, Connection} | Config];
+
+init_per_group(write_read_tests, Config) ->
+ ct:comment("Begin ~p",[grps(Config)]),
+ Config.
+
+grps(Config) ->
+ proplists:get_all_values(
+ name,
+ lists:flatten([proplists:get_value(tc_group_properties,Config,[]),
+ proplists:get_value(tc_group_path,Config,[])])).
end_per_group(erlang_server, Config) ->
+ ct:comment("End ~p",[grps(Config)]),
Config;
end_per_group(_, Config) ->
+ ct:comment("End ~p",[grps(Config)]),
Config.
%%--------------------------------------------------------------------
@@ -139,11 +225,13 @@ end_per_group(_, Config) ->
init_per_testcase(sftp_nonexistent_subsystem, Config) ->
PrivDir = ?config(priv_dir, Config),
SysDir = ?config(data_dir, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
Sftpd = ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{subsystems, []},
{user_passwords,
- [{?USER, ?PASSWD}]}
+ [{User, Passwd}]}
]),
[{sftpd, Sftpd} | Config];
@@ -153,11 +241,13 @@ init_per_testcase(version_option, Config) ->
TmpConfig = lists:keydelete(sftp, 1, TmpConfig0),
Dog = ct:timetrap(?default_timeout),
{_,Host, Port} = ?config(sftpd, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host, Port,
[{sftp_vsn, 3},
- {user, ?USER},
- {password, ?PASSWD},
+ {user, User},
+ {password, Passwd},
{user_interaction, false},
{silently_accept_hosts, true}]),
Sftp = {ChannelPid, Connection},
@@ -167,7 +257,9 @@ init_per_testcase(Case, Config0) ->
prep(Config0),
Config1 = lists:keydelete(watchdog, 1, Config0),
Config2 = lists:keydelete(sftp, 1, Config1),
- Dog = ct:timetrap(?default_timeout),
+ Dog = ct:timetrap(2 * ?default_timeout),
+ User = ?config(user, Config0),
+ Passwd = ?config(passwd, Config0),
Config =
case ?config(group,Config2) of
@@ -175,10 +267,11 @@ init_per_testcase(Case, Config0) ->
{_,Host, Port} = ?config(sftpd, Config2),
{ok, ChannelPid, Connection} =
ssh_sftp:start_channel(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
+ [{user, User},
+ {password, Passwd},
{user_interaction, false},
- {silently_accept_hosts, true}]),
+ {silently_accept_hosts, true}]
+ ),
Sftp = {ChannelPid, Connection},
[{sftp, Sftp}, {watchdog, Dog} | Config2];
openssh_server when Case == links ->
@@ -206,8 +299,7 @@ init_per_testcase(Case, Config0) ->
end_per_testcase(sftp_nonexistent_subsystem, Config) ->
Config;
end_per_testcase(rename_file, Config) ->
- PrivDir = ?config(priv_dir, Config),
- NewFileName = filename:join(PrivDir, "test.txt"),
+ NewFileName = ?config(testfile, Config),
file:delete(NewFileName),
end_per_testcase(Config);
end_per_testcase(_, Config) ->
@@ -225,8 +317,7 @@ end_per_testcase(Config) ->
open_close_file() ->
[{doc, "Test API functions open/3 and close/2"}].
open_close_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
@@ -247,7 +338,7 @@ open_close_dir() ->
open_close_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir),
ok = ssh_sftp:close(Sftp, Handle),
@@ -257,8 +348,7 @@ open_close_dir(Config) when is_list(Config) ->
read_file() ->
[{doc, "Test API funtion read_file/2"}].
read_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Data} = ssh_sftp:read_file(Sftp, FileName),
{ok, Data} = ssh_sftp:read_file(Sftp, FileName),
@@ -271,14 +361,13 @@ read_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("sftp list dir: ~p~n", [Files]).
+ ct:log("sftp list dir: ~p~n", [Files]).
%%--------------------------------------------------------------------
write_file() ->
[{doc, "Test API function write_file/2"}].
write_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("Hej hopp!"),
@@ -286,11 +375,31 @@ write_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
+write_file_iolist() ->
+ [{doc, "Test API function write_file/2 with iolists"}].
+write_file_iolist(Config) when is_list(Config) ->
+ FileName = ?config(filename, Config),
+ {Sftp, _} = ?config(sftp, Config),
+
+ Data = list_to_binary("Hej hopp!"),
+ lists:foreach(
+ fun(D) ->
+ ssh_sftp:write_file(Sftp, FileName, [D]),
+ Expected = if is_binary(D) -> D;
+ is_list(D) -> list_to_binary(D)
+ end,
+ {ok, Expected} = file:read_file(FileName)
+ end,
+ [Data, [Data,Data], [[Data],[Data]], [[[Data]],[[[[Data]],Data]]],
+ [[[[Data]],Data],binary_to_list(Data)],
+ [[[[Data]],Data],[[binary_to_list(Data)],[[binary_to_list(Data)]]]]
+ ]).
+
+%%--------------------------------------------------------------------
write_big_file() ->
[{doc, "Test API function write_file/2 with big data"}].
write_big_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary(lists:duplicate(750000,"a")),
@@ -301,8 +410,7 @@ write_big_file(Config) when is_list(Config) ->
sftp_read_big_file() ->
[{doc, "Test API function read_file/2 with big data"}].
sftp_read_big_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary(lists:duplicate(750000,"a")),
@@ -315,7 +423,7 @@ remove_file() ->
[{doc,"Test API function delete/2"}].
remove_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
@@ -329,17 +437,17 @@ rename_file() ->
[{doc, "Test API function rename_file/2"}].
rename_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
- NewFileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(filename, Config),
+ NewFileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~p, Files: ~p~n", [FileName, Files]),
+ ct:log("FileName: ~p, Files: ~p~n", [FileName, Files]),
true = lists:member(filename:basename(FileName), Files),
false = lists:member(filename:basename(NewFileName), Files),
ok = ssh_sftp:rename(Sftp, FileName, NewFileName),
{ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~p, Files: ~p~n", [FileName, NewFiles]),
+ ct:log("FileName: ~p, Files: ~p~n", [FileName, NewFiles]),
false = lists:member(filename:basename(FileName), NewFiles),
true = lists:member(filename:basename(NewFileName), NewFiles).
@@ -350,7 +458,7 @@ mk_rm_dir() ->
mk_rm_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
-
+
DirName = filename:join(PrivDir, "test"),
ok = ssh_sftp:make_dir(Sftp, DirName),
ok = ssh_sftp:del_dir(Sftp, DirName),
@@ -367,9 +475,8 @@ links(Config) when is_list(Config) ->
{skip, "Links are not fully supported by windows"};
_ ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
- LinkFileName = filename:join(PrivDir, "link_test.txt"),
+ FileName = ?config(filename, Config),
+ LinkFileName = ?config(linktest, Config),
ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName),
{ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName)
@@ -379,22 +486,20 @@ links(Config) when is_list(Config) ->
retrieve_attributes() ->
[{doc, "Test API function read_file_info/3"}].
retrieve_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName),
{ok, NewFileInfo} = file:read_file_info(FileName),
%% TODO comparison. There are some differences now is that ok?
- ct:pal("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]).
+ ct:log("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]).
%%--------------------------------------------------------------------
set_attributes() ->
[{doc,"Test API function write_file_info/3"}].
set_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok,Fd} = file:open(FileName, write),
@@ -410,26 +515,26 @@ async_read() ->
[{doc,"Test API aread/3"}].
async_read(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "sftp.txt"),
+ FileName = ?config(filename, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
{async, Ref} = ssh_sftp:aread(Sftp, Handle, 20),
receive
{async_reply, Ref, {ok, Data}} ->
- ct:pal("Data: ~p~n", [Data]),
+ ct:log("Data: ~p~n", [Data]),
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
%%--------------------------------------------------------------------
async_write() ->
[{doc,"Test API awrite/3"}].
async_write(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
Data = list_to_binary("foobar"),
{async, Ref} = ssh_sftp:awrite(Sftp, Handle, Data),
@@ -446,8 +551,7 @@ async_write(Config) when is_list(Config) ->
position() ->
[{doc, "Test API functions position/3"}].
position(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("1234567890"),
@@ -476,8 +580,7 @@ position(Config) when is_list(Config) ->
pos_read() ->
[{doc,"Test API functions pread/3 and apread/3"}].
pos_read(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
Data = list_to_binary("Hej hopp!"),
ssh_sftp:write_file(Sftp, FileName, [Data]),
@@ -492,6 +595,8 @@ pos_read(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
NewData1 = "hopp",
@@ -502,8 +607,7 @@ pos_read(Config) when is_list(Config) ->
pos_write() ->
[{doc,"Test API functions pwrite/4 and apwrite/4"}].
pos_write(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, "test.txt"),
+ FileName = ?config(testfile, Config),
{Sftp, _} = ?config(sftp, Config),
{ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
@@ -518,6 +622,8 @@ pos_write(Config) when is_list(Config) ->
ok;
Msg ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end,
ok = ssh_sftp:pwrite(Sftp, Handle, eof, list_to_binary("!")),
@@ -530,10 +636,13 @@ sftp_nonexistent_subsystem() ->
[{doc, "Try to execute sftp subsystem on a server that does not support it"}].
sftp_nonexistent_subsystem(Config) when is_list(Config) ->
{_,Host, Port} = ?config(sftpd, Config),
+ User = ?config(user, Config),
+ Passwd = ?config(passwd, Config),
{error,"server failed to start sftp subsystem"} =
ssh_sftp:start_channel(Host, Port,
[{user_interaction, false},
- {user, ?USER}, {password, ?PASSWD},
+ {user, User},
+ {password, Passwd},
{silently_accept_hosts, true}]).
%%--------------------------------------------------------------------
@@ -545,25 +654,66 @@ version_option(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
create_empty_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
erl_tar:close(Handle),
{ChPid,_} = ?config(sftp,Config),
{ok, #file_info{type=regular}} =
- ssh_sftp:read_file_info(ChPid,fnp(?tar_file_name,Config)).
+ ssh_sftp:read_file_info(ChPid, TarFileName).
%%--------------------------------------------------------------------
files_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ F1 = ?config(tar_F1_txt, Config),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose]),
+ ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([F1, "f2.txt"], Config).
+
+%%--------------------------------------------------------------------
+ascii_filename_ascii_contents_to_tar(Config) ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
ok = erl_tar:add(Handle, fn("f2.txt",Config), "f2.txt", [verbose]),
ok = erl_tar:close(Handle),
- chk_tar(["f1.txt", "f2.txt"], Config).
+ chk_tar(["f2.txt"], Config).
+
+%%--------------------------------------------------------------------
+ascii_filename_unicode_contents_to_tar(Config) ->
+ case ?config(tar_F3_txt, Config) of
+ undefined ->
+ {skip, "Unicode test"};
+ Fn ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([Fn], Config)
+ end.
+
+%%--------------------------------------------------------------------
+unicode_filename_ascii_contents_to_tar(Config) ->
+ case ?config(tar_F4_txt, Config) of
+ undefined ->
+ {skip, "Unicode test"};
+ Fn ->
+ ChPid2 = ?config(channel_pid2, Config),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ ok = erl_tar:add(Handle, fn(Fn,Config), Fn, [verbose]),
+ ok = erl_tar:close(Handle),
+ chk_tar([Fn], Config)
+ end.
%%--------------------------------------------------------------------
big_file_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose]),
ok = erl_tar:close(Handle),
chk_tar(["big.txt"], Config).
@@ -572,23 +722,27 @@ big_file_to_tar(Config) ->
%%--------------------------------------------------------------------
files_chunked_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
+ F1 = ?config(tar_F1_txt, Config),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:close(Handle),
- chk_tar(["f1.txt"], Config).
+ chk_tar([F1], Config).
%%--------------------------------------------------------------------
directory_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
ok = erl_tar:add(Handle, fn("d1",Config), "d1", [verbose]),
ok = erl_tar:close(Handle),
chk_tar(["d1"], Config).
-
+
%%--------------------------------------------------------------------
binaries_to_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
Bin = <<"A binary">>,
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
ok = erl_tar:close(Handle),
@@ -601,13 +755,15 @@ null_crypto_tar(Config) ->
Cenc = fun(Bin,CState) -> {ok,Bin,CState,_SendSize=5} end,
Cend = fun(Bin,_CState) -> {ok,Bin} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config).
+ chk_tar([{"b1",Bin}, F1, "big.txt"], Config).
%%--------------------------------------------------------------------
simple_crypto_tar_small(Config) ->
@@ -617,12 +773,14 @@ simple_crypto_tar_small(Config) ->
Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_Size=4} end,
Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+ chk_tar([{"b1",Bin}, F1], Config, [{crypto,{Cinit,Cdec}}]).
%%--------------------------------------------------------------------
simple_crypto_tar_big(Config) ->
@@ -632,18 +790,20 @@ simple_crypto_tar_big(Config) ->
Cdec = fun(Bin,CState) -> {ok,unstuff(Bin),CState,_SendSize=4} end,
Cend = fun(Bin,_CState) -> {ok,stuff(Bin)} end,
C = {Cinit,Cenc,Cend},
- {ok,Handle} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,C}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,Handle} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,C}]),
Bin = <<"A binary">>,
+ F1 = ?config(tar_F1_txt, Config),
ok = erl_tar:add(Handle, Bin, "b1", [verbose]),
- ok = erl_tar:add(Handle, fn("f1.txt",Config), "f1.txt", [verbose,{chunks,2}]),
+ ok = erl_tar:add(Handle, fn(F1,Config), F1, [verbose,{chunks,2}]),
ok = erl_tar:add(Handle, fn("big.txt",Config), "big.txt", [verbose,{chunks,15000}]),
ok = erl_tar:close(Handle),
- chk_tar([{"b1",Bin}, "f1.txt", "big.txt"], Config, [{crypto,{Cinit,Cdec}}]).
+ chk_tar([{"b1",Bin}, F1, "big.txt"], Config, [{crypto,{Cinit,Cdec}}]).
stuff(Bin) -> << <<C,C>> || <<C>> <= Bin >>.
-
+
unstuff(Bin) -> << <<C>> || <<C,C>> <= Bin >>.
-
+
%%--------------------------------------------------------------------
read_tar(Config) ->
ChPid2 = ?config(channel_pid2, Config),
@@ -651,7 +811,8 @@ read_tar(Config) ->
[{"b1",<<"A binary">>},
{"b2",list_to_binary(lists:duplicate(750000,"a"))}
]),
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -673,7 +834,8 @@ read_null_crypto_tar(Config) ->
Cw = {Cinitw,Cenc,Cendw},
Cr = {Cinitr,Cdec},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -696,7 +858,8 @@ read_crypto_tar(Config) ->
Cw = {Cinitw,Cenc,Cendw},
Cr = {Cinitr,Cdec},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose])
|| {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -735,7 +898,8 @@ aes_cbc256_crypto_tar(Config) ->
end,
Cw = {Cinitw,Cenc,Cendw},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -777,7 +941,8 @@ aes_ctr_stream_crypto_tar(Config) ->
end,
Cw = {Cinitw,Cenc,Cendw},
- {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, fnp(?tar_file_name,Config), [write,{crypto,Cw}]),
+ TarFileName = ?config(tar_filename, Config),
+ {ok,HandleWrite} = ssh_sftp:open_tar(ChPid2, TarFileName, [write,{crypto,Cw}]),
[ok = erl_tar:add(HandleWrite, Bin, Name, [verbose]) || {Name,Bin} <- NameBins],
ok = erl_tar:close(HandleWrite),
@@ -788,18 +953,18 @@ aes_ctr_stream_crypto_tar(Config) ->
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
prep(Config) ->
- PrivDir = ?config(priv_dir, Config),
- TestFile = filename:join(PrivDir, "sftp.txt"),
- TestFile1 = filename:join(PrivDir, "test.txt"),
- TestLink = filename:join(PrivDir, "link_test.txt"),
+ DataDir = ?config(data_dir, Config),
+ TestFile = ?config(filename, Config),
+ TestFile1 = ?config(testfile, Config),
+ TestLink = ?config(linktest, Config),
+ TarFileName = ?config(tar_filename, Config),
file:delete(TestFile),
file:delete(TestFile1),
file:delete(TestLink),
- file:delete(fnp(?tar_file_name,Config)),
+ file:delete(TarFileName),
%% Initial config
- DataDir = ?config(data_dir, Config),
FileName = filename:join(DataDir, "sftp.txt"),
file:copy(FileName, TestFile),
Mode = 8#00400 bor 8#00200 bor 8#00040, % read & write owner, read group
@@ -807,13 +972,12 @@ prep(Config) ->
ok = file:write_file_info(TestFile,
FileInfo#file_info{mode = Mode}).
-
-
chk_tar(Items, Config) ->
chk_tar(Items, Config, []).
chk_tar(Items, Config, Opts) ->
- chk_tar(Items, fnp(?tar_file_name,Config), Config, Opts).
+ TarFileName = ?config(tar_filename, Config),
+ chk_tar(Items, TarFileName, Config, Opts).
chk_tar(Items, TarFileName, Config, Opts) when is_list(Opts) ->
tar_size(TarFileName, Config),
@@ -844,7 +1008,7 @@ analyze_report([E={NameE,BinE}|Es], [A={NameA,BinA}|As]) ->
NameE < NameA ->
[["Component ",NameE," is missing.\n\n"]
| analyze_report(Es,[A|As])];
-
+
NameE > NameA ->
[["Component ",NameA," is not expected.\n\n"]
| analyze_report([E|Es],As)];
@@ -857,7 +1021,7 @@ analyze_report([], [{NameA,_BinA}|As]) ->
[["Component ",NameA," not expected.\n\n"] | analyze_report([],As)];
analyze_report([], []) ->
"".
-
+
tar_size(TarFileName, Config) ->
{ChPid,_} = ?config(sftp,Config),
{ok,Data} = ssh_sftp:read_file(ChPid, TarFileName),
@@ -886,14 +1050,9 @@ read_item_contents(ItemName, FileName) ->
end.
fn(Name, Config) ->
- Dir = ?config(data_dir, Config),
- filename:join([Dir,"sftp_tar_test_data",Name]).
-
-fnp(Name, Config) ->
- Dir = ?config(priv_dir, Config),
- filename:join([Dir,Name]).
-
+ Dir = ?config(datadir_tar, Config),
+ filename:join(Dir,Name).
fmt_host({A,B,C,D}) -> lists:concat([A,".",B,".",C,".",D]);
fmt_host(S) -> S.
-
+
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt
new file mode 100644
index 0000000000..e6076a05b5
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/F一.txt
@@ -0,0 +1 @@
+你好
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt
new file mode 100644
index 0000000000..f597b69d4c
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/big.txt
@@ -0,0 +1,16384 @@
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
+All work and no play makes Jack a dull boy.
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1
new file mode 100644
index 0000000000..1bafa9761e
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f1
@@ -0,0 +1 @@
+And hi from the subdirectory too!
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2 b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2
new file mode 100644
index 0000000000..8566adaeef
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/d1/f2
@@ -0,0 +1 @@
+one more file
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt
new file mode 100644
index 0000000000..d18c6b11fc
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f2.txt
@@ -0,0 +1 @@
+How are you?
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt
new file mode 100644
index 0000000000..e6076a05b5
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/f3.txt
@@ -0,0 +1 @@
+你好
diff --git a/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt
new file mode 100644
index 0000000000..d18c6b11fc
--- /dev/null
+++ b/lib/ssh/test/ssh_sftp_SUITE_data/sftp_tar_test_data_高兴/g四.txt
@@ -0,0 +1 @@
+How are you?
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 0ce8eec906..6b03a2b763 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2006-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -68,6 +69,7 @@ groups() ->
%%--------------------------------------------------------------------
init_per_suite(Config) ->
+ catch crypto:stop(),
case (catch crypto:start()) of
ok ->
DataDir = ?config(data_dir, Config),
@@ -150,7 +152,7 @@ init_per_testcase(TestCase, Config) ->
{ok, <<?SSH_FXP_VERSION, ?UINT32(Version), _Ext/binary>>, _}
= reply(Cm, Channel),
- ct:pal("Client: ~p Server ~p~n", [ProtocolVer, Version]),
+ ct:log("Client: ~p Server ~p~n", [ProtocolVer, Version]),
[{sftp, {Cm, Channel}}, {sftpd, Sftpd }| Config].
@@ -416,7 +418,7 @@ real_path(Config) when is_list(Config) ->
RealPath = filename:absname(binary_to_list(Path)),
AbsPrivDir = filename:absname(PrivDir),
- ct:pal("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]),
+ ct:log("Path: ~p PrivDir: ~p~n", [RealPath, AbsPrivDir]),
true = RealPath == AbsPrivDir
end.
@@ -445,7 +447,7 @@ links(Config) when is_list(Config) ->
true = binary_to_list(Path) == FileName,
- ct:pal("Path: ~p~n", [binary_to_list(Path)])
+ ct:log("Path: ~p~n", [binary_to_list(Path)])
end.
%%--------------------------------------------------------------------
@@ -546,10 +548,10 @@ set_attributes(Config) when is_list(Config) ->
%% Can not test that NewPermissions = Permissions as
%% on Unix platforms, other bits than those listed in the
%% API may be set.
- ct:pal("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]),
+ ct:log("Org: ~p New: ~p~n", [OrigPermissions, NewPermissions]),
true = OrigPermissions =/= NewPermissions,
- ct:pal("Try to open the file"),
+ ct:log("Try to open the file"),
NewReqId = 2,
{ok, <<?SSH_FXP_HANDLE, ?UINT32(NewReqId), Handle/binary>>, _} =
open_file(FileName, Cm, Channel, NewReqId,
@@ -561,7 +563,7 @@ set_attributes(Config) when is_list(Config) ->
NewReqId1 = 3,
- ct:pal("Set original permissions on the now open file"),
+ ct:log("Set original permissions on the now open file"),
{ok, <<?SSH_FXP_STATUS, ?UINT32(NewReqId1),
?UINT32(?SSH_FX_OK), _/binary>>, _} =
@@ -681,6 +683,8 @@ reply(Cm, Channel, RBuf) ->
closed;
{ssh_cm, Cm, Msg} ->
ct:fail(Msg)
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -784,7 +788,7 @@ read_dir(Handle, Cm, Channel, ReqId) ->
case reply(Cm, Channel) of
{ok, <<?SSH_FXP_NAME, ?UINT32(ReqId), ?UINT32(Count),
?UINT32(Len), Listing:Len/binary, _/binary>>, _} ->
- ct:pal("Count: ~p Listing: ~p~n",
+ ct:log("Count: ~p Listing: ~p~n",
[Count, binary_to_list(Listing)]),
read_dir(Handle, Cm, Channel, ReqId);
{ok, <<?SSH_FXP_STATUS, ?UINT32(ReqId),
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
index cc34cc0793..7a025a6518 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -52,6 +53,7 @@ groups() ->
init_per_suite(Config) ->
catch ssh:stop(),
+ catch crypto:stop(),
case catch crypto:start() of
ok ->
DataDir = ?config(data_dir, Config),
@@ -157,7 +159,7 @@ close_file(Config) when is_list(Config) ->
NumOfPorts = length(erlang:ports()),
- ct:pal("Number of open ports: ~p~n", [NumOfPorts]),
+ ct:log("Number of open ports: ~p~n", [NumOfPorts]),
{ok, <<_/binary>>} = ssh_sftp:read_file(Sftp, FileName),
@@ -253,14 +255,14 @@ root_dir(Config) when is_list(Config) ->
{ok, Bin} = ssh_sftp:read_file(Sftp, FileName),
{ok, Listing} =
ssh_sftp:list_dir(Sftp, "."),
- ct:pal("Listing: ~p~n", [Listing]).
+ ct:log("Listing: ~p~n", [Listing]).
%%--------------------------------------------------------------------
list_dir_limited(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
{ok, Listing} =
ssh_sftp:list_dir(Sftp, "."),
- ct:pal("Listing: ~p~n", [Listing]).
+ ct:log("Listing: ~p~n", [Listing]).
%%--------------------------------------------------------------------
ver6_basic() ->
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
index 8ad383d8c9..4f494cf829 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE_data/ssh_sftpd_file_alt.erl
@@ -3,16 +3,17 @@
%%
%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
diff --git a/lib/ssh/test/ssh_sup_SUITE.erl b/lib/ssh/test/ssh_sup_SUITE.erl
new file mode 100644
index 0000000000..5c77fcf1ef
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE.erl
@@ -0,0 +1,193 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssh_sup_SUITE).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-define(WAIT_FOR_SHUTDOWN, 500).
+-define(USER, "Alladin").
+-define(PASSWD, "Sesame").
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+all() ->
+ [default_tree, sshc_subtree, sshd_subtree, sshd_subtree_profile].
+
+groups() ->
+ [].
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+init_per_suite(Config) ->
+ Port = ssh_test_lib:inet_port(node()),
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ [{userdir, UserDir},{port, Port}, {host, "localhost"}, {host_ip, any} | Config].
+
+end_per_suite(_) ->
+ ok.
+
+init_per_testcase(sshc_subtree, Config) ->
+ ssh:start(),
+ SystemDir = ?config(data_dir, Config),
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}]),
+ [{server, {Pid, Host, Port}} | Config];
+init_per_testcase(Case, Config) ->
+ end_per_testcase(Case, Config),
+ ssh:start(),
+ Config.
+end_per_testcase(sshc_subtree, Config) ->
+ {Pid,_,_} = ?config(server, Config),
+ ssh:stop_daemon(Pid),
+ ssh:stop();
+end_per_testcase(_, _Config) ->
+ ssh:stop().
+
+%%-------------------------------------------------------------------------
+%% Test cases
+%%-------------------------------------------------------------------------
+default_tree() ->
+ [{doc, "Makes sure the correct processes are started and linked,"
+ "in the default case."}].
+default_tree(Config) when is_list(Config) ->
+ TopSupChildren = supervisor:which_children(ssh_sup),
+ 2 = length(TopSupChildren),
+ {value, {sshc_sup, _, supervisor,[sshc_sup]}} =
+ lists:keysearch(sshc_sup, 1, TopSupChildren),
+ {value, {sshd_sup, _,supervisor,[sshd_sup]}} =
+ lists:keysearch(sshd_sup, 1, TopSupChildren),
+ [] = supervisor:which_children(sshc_sup),
+ [] = supervisor:which_children(sshd_sup).
+
+sshc_subtree() ->
+ [{doc, "Make sure the sshc subtree is correct"}].
+sshc_subtree(Config) when is_list(Config) ->
+ {_Pid, Host, Port} = ?config(server, Config),
+ UserDir = ?config(userdir, Config),
+
+ [] = supervisor:which_children(sshc_sup),
+ {ok, Pid1} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]),
+ [{_, _,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ {ok, Pid2} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD}, {user_dir, UserDir}]),
+ [{_,_,supervisor,[ssh_connection_handler]},
+ {_,_,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ ssh:close(Pid1),
+ [{_,_,supervisor,[ssh_connection_handler]}] =
+ supervisor:which_children(sshc_sup),
+ ssh:close(Pid2),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshc_sup).
+
+sshd_subtree() ->
+ [{doc, "Make sure the sshd subtree is correct"}].
+sshd_subtree(Config) when is_list(Config) ->
+ HostIP = ?config(host_ip, Config),
+ Port = ?config(port, Config),
+ SystemDir = ?config(data_dir, Config),
+ ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}]),
+ [{{server,ssh_system_sup, HostIP, Port, ?DEFAULT_PROFILE},
+ Daemon, supervisor,
+ [ssh_system_sup]}] =
+ supervisor:which_children(sshd_sup),
+ check_sshd_system_tree(Daemon, Config),
+ ssh:stop_daemon(HostIP, Port),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshd_sup).
+
+sshd_subtree_profile() ->
+ [{doc, "Make sure the sshd subtree using profile option is correct"}].
+sshd_subtree_profile(Config) when is_list(Config) ->
+ HostIP = ?config(host_ip, Config),
+ Port = ?config(port, Config),
+ Profile = ?config(profile, Config),
+ SystemDir = ?config(data_dir, Config),
+
+ {ok, _} = ssh:daemon(HostIP, Port, [{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2},
+ {user_passwords,
+ [{?USER, ?PASSWD}]},
+ {profile, Profile}]),
+ [{{server,ssh_system_sup, HostIP,Port,Profile},
+ Daemon, supervisor,
+ [ssh_system_sup]}] =
+ supervisor:which_children(sshd_sup),
+ check_sshd_system_tree(Daemon, Config),
+ ssh:stop_daemon(HostIP, Port, Profile),
+ ct:sleep(?WAIT_FOR_SHUTDOWN),
+ [] = supervisor:which_children(sshd_sup).
+
+
+check_sshd_system_tree(Daemon, Config) ->
+ Host = ?config(host, Config),
+ Port = ?config(port, Config),
+ UserDir = ?config(userdir, Config),
+ {ok, Client} = ssh:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]),
+
+ [{_,SubSysSup, supervisor,[ssh_subsystem_sup]},
+ {{ssh_acceptor_sup,_,_,_}, AccSup, supervisor,[ssh_acceptor_sup]}]
+ = supervisor:which_children(Daemon),
+
+ [{{server,ssh_connection_sup, _,_},
+ ConnectionSup, supervisor,
+ [ssh_connection_sup]},
+ {{server,ssh_channel_sup,_ ,_},
+ ChannelSup,supervisor,
+ [ssh_channel_sup]}] = supervisor:which_children(SubSysSup),
+
+ [{{ssh_acceptor_sup,_,_,_},_,worker,[ssh_acceptor]}] =
+ supervisor:which_children(AccSup),
+
+ [{_, _, worker,[ssh_connection_handler]}] =
+ supervisor:which_children(ConnectionSup),
+
+ [] = supervisor:which_children(ChannelSup),
+
+ ssh_sftp:start_channel(Client),
+
+ [{_, _,worker,[ssh_channel]}] =
+ supervisor:which_children(ChannelSup),
+ ssh:close(Client).
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/id_dsa b/lib/ssh/test/ssh_sup_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/id_rsa b/lib/ssh/test/ssh_sup_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_sup_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index b8abf5e80e..2db55b97b4 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -26,6 +27,8 @@
-include_lib("public_key/include/public_key.hrl").
-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh_transport.hrl").
+
-define(TIMEOUT, 50000).
@@ -64,6 +67,61 @@ daemon(Host, Port, Options) ->
end.
+std_daemon(Config, ExtraOpts) ->
+ PrivDir = ?config(priv_dir, Config),
+ UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
+ file:make_dir(UserDir),
+ std_daemon1(Config,
+ ExtraOpts ++
+ [{user_dir, UserDir},
+ {user_passwords, [{"usr1","pwd1"}]}]).
+
+std_daemon1(Config, ExtraOpts) ->
+ SystemDir = ?config(data_dir, Config),
+ {_Server, _Host, _Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {failfun, fun ssh_test_lib:failfun/2}
+ | ExtraOpts]).
+
+std_connect(Config, Host, Port, ExtraOpts) ->
+ UserDir = ?config(priv_dir, Config),
+ _ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user, "usr1"},
+ {password, "pwd1"},
+ {user_interaction, false}
+ | ExtraOpts]).
+
+std_simple_sftp(Host, Port, Config) ->
+ std_simple_sftp(Host, Port, Config, []).
+
+std_simple_sftp(Host, Port, Config, Opts) ->
+ UserDir = ?config(priv_dir, Config),
+ DataFile = filename:join(UserDir, "test.data"),
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ {ok, ChannelRef} = ssh_sftp:start_channel(ConnectionRef),
+ Data = crypto:rand_bytes(proplists:get_value(std_simple_sftp_size,Config,10)),
+ ok = ssh_sftp:write_file(ChannelRef, DataFile, Data),
+ {ok,ReadData} = file:read_file(DataFile),
+ ok = ssh:close(ConnectionRef),
+ Data == ReadData.
+
+std_simple_exec(Host, Port, Config) ->
+ std_simple_exec(Host, Port, Config, []).
+
+std_simple_exec(Host, Port, Config, Opts) ->
+ ConnectionRef = ssh_test_lib:std_connect(Config, Host, Port, Opts),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId, "23+21-2.", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"42\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ok;
+ Other ->
+ ct:fail(Other)
+ end,
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId).
+
start_shell(Port, IOServer, UserDir) ->
start_shell(Port, IOServer, UserDir, []).
@@ -96,16 +154,18 @@ loop_io_server(TestCase, Buff0) ->
{input, TestCase, Line} ->
loop_io_server(TestCase, Buff0 ++ [Line]);
{io_request, From, ReplyAs, Request} ->
-%%ct:pal("~p",[{io_request, From, ReplyAs, Request}]),
+%%ct:log("~p",[{io_request, From, ReplyAs, Request}]),
{ok, Reply, Buff} = io_request(Request, TestCase, From,
ReplyAs, Buff0),
-%%ct:pal("io_request(~p)-->~p",[Request,{ok, Reply, Buff}]),
+%%ct:log("io_request(~p)-->~p",[Request,{ok, Reply, Buff}]),
io_reply(From, ReplyAs, Reply),
loop_io_server(TestCase, Buff);
{'EXIT',_, _} ->
erlang:display('ssh_test_lib:loop_io_server/2 EXIT'),
ok
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
io_request({put_chars, Chars}, TestCase, _, _, Buff) ->
reply(TestCase, Chars),
@@ -133,27 +193,29 @@ io_request({get_line, _Enc,_}, _, _, _, [Line | Buff]) ->
io_reply(_, _, []) ->
ok;
io_reply(From, ReplyAs, Reply) ->
-%%ct:pal("io_reply ~p sending ~p ! ~p",[self(),From, {io_reply, ReplyAs, Reply}]),
+%%ct:log("io_reply ~p sending ~p ! ~p",[self(),From, {io_reply, ReplyAs, Reply}]),
From ! {io_reply, ReplyAs, Reply}.
reply(_, []) ->
ok;
reply(TestCase, Result) ->
-%%ct:pal("reply ~p sending ~p ! ~p",[self(), TestCase, Result]),
+%%ct:log("reply ~p sending ~p ! ~p",[self(), TestCase, Result]),
TestCase ! Result.
receive_exec_result(Msg) ->
- ct:pal("Expect data! ~p", [Msg]),
+ ct:log("Expect data! ~p", [Msg]),
receive
{ssh_cm,_,{data,_,1, Data}} ->
- ct:pal("StdErr: ~p~n", [Data]),
+ ct:log("StdErr: ~p~n", [Data]),
receive_exec_result(Msg);
Msg ->
- ct:pal("1: Collected data ~p", [Msg]),
+ ct:log("1: Collected data ~p", [Msg]),
expected;
Other ->
- ct:pal("Other ~p", [Other]),
+ ct:log("Other ~p", [Other]),
{unexpected_msg, Other}
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
@@ -164,15 +226,15 @@ receive_exec_end(ConnectionRef, ChannelId) ->
case receive_exec_result(ExitStatus) of
{unexpected_msg, Eof} -> %% Open ssh seems to not allways send these messages
%% in the same order!
- ct:pal("2: Collected data ~p", [Eof]),
+ ct:log("2: Collected data ~p", [Eof]),
case receive_exec_result(ExitStatus) of
expected ->
expected = receive_exec_result(Closed);
{unexpected_msg, Closed} ->
- ct:pal("3: Collected data ~p", [Closed])
+ ct:log("3: Collected data ~p", [Closed])
end;
expected ->
- ct:pal("4: Collected data ~p", [ExitStatus]),
+ ct:log("4: Collected data ~p", [ExitStatus]),
expected = receive_exec_result(Eof),
expected = receive_exec_result(Closed);
Other ->
@@ -234,6 +296,7 @@ setup_dsa(DataDir, UserDir) ->
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_dsa_key"), filename:join(System, "ssh_host_dsa_key")),
file:copy(filename:join(DataDir, "ssh_host_dsa_key.pub"), filename:join(System, "ssh_host_dsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_dsa_known_host(DataDir, UserDir),
setup_dsa_auth_keys(DataDir, UserDir).
@@ -242,10 +305,21 @@ setup_rsa(DataDir, UserDir) ->
System = filename:join(UserDir, "system"),
file:make_dir(System),
file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key")),
- file:copy(filename:join(DataDir, "ssh_host_rsa_key"), filename:join(System, "ssh_host_rsa_key.pub")),
+ file:copy(filename:join(DataDir, "ssh_host_rsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_rsa_known_host(DataDir, UserDir),
setup_rsa_auth_keys(DataDir, UserDir).
+setup_ecdsa(Size, DataDir, UserDir) ->
+ file:copy(filename:join(DataDir, "id_ecdsa"++Size), filename:join(UserDir, "id_ecdsa")),
+ System = filename:join(UserDir, "system"),
+ file:make_dir(System),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
+ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
+ setup_ecdsa_known_host(Size, System, UserDir),
+ setup_ecdsa_auth_keys(Size, UserDir, UserDir).
+
clean_dsa(UserDir) ->
del_dirs(filename:join(UserDir, "system")),
file:delete(filename:join(UserDir,"id_dsa")),
@@ -297,6 +371,11 @@ setup_rsa_known_host(SystemDir, UserDir) ->
[{Key, _}] = public_key:ssh_decode(SshBin, public_key),
setup_known_hosts(Key, UserDir).
+setup_ecdsa_known_host(_Size, SystemDir, UserDir) ->
+ {ok, SshBin} = file:read_file(filename:join(SystemDir, "ssh_host_ecdsa_key.pub")),
+ [{Key, _}] = public_key:ssh_decode(SshBin, public_key),
+ setup_known_hosts(Key, UserDir).
+
setup_known_hosts(Key, UserDir) ->
{ok, Hostname} = inet:gethostname(),
{ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
@@ -324,6 +403,14 @@ setup_rsa_auth_keys(Dir, UserDir) ->
PKey = #'RSAPublicKey'{publicExponent = E, modulus = N},
setup_auth_keys([{ PKey, [{comment, "Test"}]}], UserDir).
+setup_ecdsa_auth_keys(_Size, Dir, UserDir) ->
+ {ok, Pem} = file:read_file(filename:join(Dir, "id_ecdsa")),
+ ECDSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
+ #'ECPrivateKey'{publicKey = Q,
+ parameters = Param = {namedCurve,_Id0}} = ECDSA,
+ PKey = #'ECPoint'{point = Q},
+ setup_auth_keys([{ {PKey,Param}, [{comment, "Test"}]}], UserDir).
+
setup_auth_keys(Keys, Dir) ->
AuthKeys = public_key:ssh_encode(Keys, auth_keys),
AuthKeysFile = filename:join(Dir, "authorized_keys"),
@@ -358,3 +445,249 @@ do_inet_port(Node) ->
{ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
{ok, Port} = rpc:call(Node, inet, port, [Socket]),
{Port, Socket}.
+
+openssh_sanity_check(Config) ->
+ ssh:start(),
+ case ssh:connect("localhost", 22, [{password,""}]) of
+ {ok, Pid} ->
+ ssh:close(Pid),
+ ssh:stop(),
+ Config;
+ Err ->
+ Str = lists:append(io_lib:format("~p", [Err])),
+ ssh:stop(),
+ {skip, Str}
+ end.
+
+openssh_supports(ClientOrServer, Tag, Alg) when ClientOrServer == sshc ;
+ ClientOrServer == sshd ->
+ SSH_algos = ssh_test_lib:default_algorithms(ClientOrServer),
+ L = proplists:get_value(Tag, SSH_algos, []),
+ lists:member(Alg, L) orelse
+ lists:member(Alg, proplists:get_value(client2server, L, [])) orelse
+ lists:member(Alg, proplists:get_value(server2client, L, [])).
+
+%%--------------------------------------------------------------------
+%% Check if we have a "newer" ssh client that supports these test cases
+
+ssh_client_supports_Q() ->
+ ErlPort = open_port({spawn, "ssh -Q cipher"}, [exit_status, stderr_to_stdout]),
+ 0 == check_ssh_client_support2(ErlPort).
+
+check_ssh_client_support2(P) ->
+ receive
+ {P, {data, _A}} ->
+ check_ssh_client_support2(P);
+ {P, {exit_status, E}} ->
+ E
+ after 5000 ->
+
+ ct:log("Openssh command timed out ~n"),
+ -1
+ end.
+
+%%%--------------------------------------------------------------------
+%%% Probe a server or a client about algorithm support
+
+default_algorithms(sshd) ->
+ default_algorithms(sshd, "localhost", 22);
+
+default_algorithms(sshc) ->
+ default_algorithms(sshc, []).
+
+default_algorithms(sshd, Host, Port) ->
+ try run_fake_ssh(
+ ssh_trpt_test_lib:exec(
+ [{connect,Host,Port, [{silently_accept_hosts, true},
+ {user_interaction, false}]}]))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end.
+
+default_algorithms(sshc, DaemonOptions) ->
+ Parent = self(),
+ %% Start a process handling one connection on the server side:
+ Srvr =
+ spawn_link(
+ fun() ->
+ Parent !
+ {result, self(),
+ try
+ {ok,InitialState} = ssh_trpt_test_lib:exec(listen),
+ Parent ! {hostport,self(),ssh_trpt_test_lib:server_host_port(InitialState)},
+ run_fake_ssh(
+ ssh_trpt_test_lib:exec([{accept, DaemonOptions}],
+ InitialState))
+ catch
+ _C:_E ->
+ ct:log("***~p:~p: ~p:~p",[?MODULE,?LINE,_C,_E]),
+ []
+ end}
+ end),
+
+ receive
+ {hostport,Srvr,{_Host,Port}} ->
+ spawn(fun()-> os:cmd(lists:concat(["ssh -o \"StrictHostKeyChecking no\" -p ",Port," localhost"])) end)
+ after ?TIMEOUT ->
+ ct:fail("No server respons 1")
+ end,
+
+ receive
+ {result,Srvr,L} ->
+ L
+ after ?TIMEOUT ->
+ ct:fail("No server respons 2")
+ end.
+
+run_fake_ssh({ok,InitialState}) ->
+ KexInitPattern =
+ #ssh_msg_kexinit{
+ kex_algorithms = '$kex_algorithms',
+ server_host_key_algorithms = '$server_host_key_algorithms',
+ encryption_algorithms_client_to_server = '$encryption_algorithms_client_to_server',
+ encryption_algorithms_server_to_client = '$encryption_algorithms_server_to_client',
+ mac_algorithms_client_to_server = '$mac_algorithms_client_to_server',
+ mac_algorithms_server_to_client = '$mac_algorithms_server_to_client',
+ compression_algorithms_client_to_server = '$compression_algorithms_client_to_server',
+ compression_algorithms_server_to_client = '$compression_algorithms_server_to_client',
+ _ = '_'
+ },
+ {ok,E} = ssh_trpt_test_lib:exec([{set_options,[silent]},
+ {send, hello},
+ receive_hello,
+ {send, ssh_msg_kexinit},
+ {match, KexInitPattern, receive_msg},
+ close_socket
+ ],
+ InitialState),
+ [Kex, PubKey, EncC2S, EncS2C, MacC2S, MacS2C, CompC2S, CompS2C] =
+ ssh_trpt_test_lib:instantiate(['$kex_algorithms',
+ '$server_host_key_algorithms',
+ '$encryption_algorithms_client_to_server',
+ '$encryption_algorithms_server_to_client',
+ '$mac_algorithms_client_to_server',
+ '$mac_algorithms_server_to_client',
+ '$compression_algorithms_client_to_server',
+ '$compression_algorithms_server_to_client'
+ ], E),
+ [{kex, to_atoms(Kex)},
+ {public_key, to_atoms(PubKey)},
+ {cipher, [{client2server, to_atoms(EncC2S)},
+ {server2client, to_atoms(EncS2C)}]},
+ {mac, [{client2server, to_atoms(MacC2S)},
+ {server2client, to_atoms(MacS2C)}]},
+ {compression, [{client2server, to_atoms(CompC2S)},
+ {server2client, to_atoms(CompS2C)}]}].
+
+
+%%%----------------------------------------------------------------
+extract_algos(Spec) ->
+ [{Tag,get_atoms(List)} || {Tag,List} <- Spec].
+
+get_atoms(L) ->
+ lists:usort(
+ [ A || X <- L,
+ A <- case X of
+ {_,L1} when is_list(L1) -> L1;
+ Y when is_atom(Y) -> [Y]
+ end]).
+
+
+intersection(AlgoSpec1, AlgoSpec2) -> intersect(sort_spec(AlgoSpec1), sort_spec(AlgoSpec2)).
+
+intersect([{Tag,S1}|Ss1], [{Tag,S2}|Ss2]) ->
+ [{Tag,intersect(S1,S2)} | intersect(Ss1,Ss2)];
+intersect(L1=[A1|_], L2=[A2|_]) when is_atom(A1),is_atom(A2) ->
+ Diff = L1 -- L2,
+ L1 -- Diff;
+intersect(_, _) ->
+ [].
+
+intersect_bi_dir([{Tag,[{client2server,L1},{server2client,L2}]}|T]) ->
+ [{Tag,intersect(L1,L2)} | intersect_bi_dir(T)];
+intersect_bi_dir([H={_,[A|_]}|T]) when is_atom(A) ->
+ [H | intersect_bi_dir(T)];
+intersect_bi_dir([]) ->
+ [].
+
+
+sort_spec(L = [{_,_}|_] ) -> [{Tag,sort_spec(Es)} || {Tag,Es} <- L];
+sort_spec(L) -> lists:usort(L).
+
+%%--------------------------------------------------------------------
+sshc(Tag) ->
+ to_atoms(
+ string:tokens(os:cmd(lists:concat(["ssh -Q ",Tag])), "\n")
+ ).
+
+ssh_type() ->
+ case os:find_executable("ssh") of
+ false -> not_found;
+ _ ->
+ case os:cmd("ssh -V") of
+ "OpenSSH" ++ _ ->
+ openSSH;
+ Str ->
+ ct:log("ssh client ~p is unknown",[Str]),
+ unknown
+ end
+ end.
+
+algo_intersection([], _) -> [];
+algo_intersection(_, []) -> [];
+algo_intersection(L1=[A1|_], L2=[A2|_]) when is_atom(A1), is_atom(A2) ->
+ true = lists:all(fun erlang:is_atom/1, L1++L2),
+ lists:foldr(fun(A,Acc) ->
+ case lists:member(A,L2) of
+ true -> [A|Acc];
+ false -> Acc
+ end
+ end, [], L1);
+algo_intersection([{K,V1}|T1], L2) ->
+ case lists:keysearch(K,1,L2) of
+ {value, {K,V2}} ->
+ [{K,algo_intersection(V1,V2)} | algo_intersection(T1,L2)];
+ false ->
+ algo_intersection(T1,L2)
+ end;
+algo_intersection(_, _) ->
+ [].
+
+
+to_atoms(L) -> lists:map(fun erlang:list_to_atom/1, L).
+
+%%%----------------------------------------------------------------
+ssh_supports(Alg, SshDefaultAlg_tag) ->
+ SupAlgs =
+ case proplists:get_value(SshDefaultAlg_tag,
+ ssh:default_algorithms()) of
+ [{_K1,L1}, {_K2,L2}] ->
+ lists:usort(L1++L2);
+ L ->
+ L
+ end,
+ if
+ is_atom(Alg) ->
+ lists:member(Alg, SupAlgs);
+ is_list(Alg) ->
+ case Alg--SupAlgs of
+ [] ->
+ true;
+ UnSup ->
+ {false,UnSup}
+ end
+ end.
+
+%%%----------------------------------------------------------------
+has_inet6_address() ->
+ try
+ [throw(6) || {ok,L} <- [inet:getifaddrs()],
+ {_,L1} <- L,
+ {addr,{_,_,_,_,_,_,_,_}} <- L1]
+ of
+ [] -> false
+ catch
+ throw:6 -> true
+ end.
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index af70eeb46c..67a61d3c11 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -1,18 +1,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. All Rights Reserved.
%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
+%% 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
%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
+%% 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.
%%
%% %CopyrightEnd%
%%
@@ -44,29 +45,26 @@ all() ->
groups() ->
[{erlang_client, [], [erlang_shell_client_openssh_server,
- erlang_client_openssh_server_exec,
erlang_client_openssh_server_exec_compressed,
erlang_client_openssh_server_setenv,
erlang_client_openssh_server_publickey_rsa,
erlang_client_openssh_server_publickey_dsa,
erlang_client_openssh_server_password,
+ erlang_client_openssh_server_kexs,
erlang_client_openssh_server_nonexistent_subsystem
]},
- {erlang_server, [], [erlang_server_openssh_client_exec,
- erlang_server_openssh_client_exec_compressed,
- erlang_server_openssh_client_pulic_key_dsa,
- erlang_server_openssh_client_cipher_suites,
- erlang_server_openssh_client_macs]}
+ {erlang_server, [], [erlang_server_openssh_client_public_key_dsa]}
].
init_per_suite(Config) ->
+ catch crypto:stop(),
case catch crypto:start() of
ok ->
case gen_tcp:connect("localhost", 22, []) of
{error,econnrefused} ->
{skip,"No openssh deamon"};
_ ->
- Config
+ ssh_test_lib:openssh_sanity_check(Config)
end;
_Else ->
{skip,"Could not start crypto!"}
@@ -81,6 +79,11 @@ init_per_group(erlang_server, Config) ->
UserDir = ?config(priv_dir, Config),
ssh_test_lib:setup_dsa_known_host(DataDir, UserDir),
Config;
+init_per_group(erlang_client, Config) ->
+ CommonAlgs = ssh_test_lib:algo_intersection(
+ ssh:default_algorithms(),
+ ssh_test_lib:default_algorithms(sshd)),
+ [{common_algs,CommonAlgs} | Config];
init_per_group(_, Config) ->
Config.
@@ -91,12 +94,11 @@ end_per_group(erlang_server, Config) ->
end_per_group(_, Config) ->
Config.
-init_per_testcase(erlang_server_openssh_client_cipher_suites, Config) ->
- check_ssh_client_support(Config);
-
-init_per_testcase(erlang_server_openssh_client_macs, Config) ->
- check_ssh_client_support(Config);
+init_per_testcase(erlang_server_openssh_client_public_key_dsa, Config) ->
+ chk_key(sshc, 'ssh-dss', ".ssh/id_dsa", Config);
+init_per_testcase(erlang_client_openssh_server_publickey_dsa, Config) ->
+ chk_key(sshd, 'ssh-dss', ".ssh/id_dsa", Config);
init_per_testcase(_TestCase, Config) ->
ssh:start(),
Config.
@@ -105,6 +107,27 @@ end_per_testcase(_TestCase, _Config) ->
ssh:stop(),
ok.
+
+chk_key(Pgm, Name, File, Config) ->
+ case ssh_test_lib:openssh_supports(Pgm, public_key, Name) of
+ false ->
+ {skip,lists:concat(["openssh client does not support ",Name])};
+ true ->
+ {ok,[[Home]]} = init:get_argument(home),
+ KeyFile = filename:join(Home, File),
+ case file:read_file(KeyFile) of
+ {ok, Pem} ->
+ case public_key:pem_decode(Pem) of
+ [{_,_, not_encrypted}] ->
+ init_per_testcase('__default__',Config);
+ _ ->
+ {skip, {error, "Has pass phrase can not be used by automated test case"}}
+ end;
+ _ ->
+ {skip, lists:concat(["no ~/",File])}
+ end
+ end.
+
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
@@ -138,7 +161,7 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) ->
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId0);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId0, 0}}
= ExitStatus0} ->
- ct:pal("0: Collected data ~p", [ExitStatus0]),
+ ct:log("0: Collected data ~p", [ExitStatus0]),
ssh_test_lib:receive_exec_result(Data0,
ConnectionRef, ChannelId0);
Other0 ->
@@ -154,7 +177,7 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) ->
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId1);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId1, 0}}
= ExitStatus1} ->
- ct:pal("0: Collected data ~p", [ExitStatus1]),
+ ct:log("0: Collected data ~p", [ExitStatus1]),
ssh_test_lib:receive_exec_result(Data1,
ConnectionRef, ChannelId1);
Other1 ->
@@ -166,184 +189,81 @@ erlang_client_openssh_server_exec_compressed() ->
[{doc, "Test that compression option works"}].
erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) ->
- ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
- {user_interaction, false},
- {compression, zlib}]),
- {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
- success = ssh_connection:exec(ConnectionRef, ChannelId,
- "echo testing", infinity),
- Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
- case ssh_test_lib:receive_exec_result(Data) of
- expected ->
- ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
- {unexpected_msg,{ssh_cm, ConnectionRef,
- {exit_status, ChannelId, 0}} = ExitStatus} ->
- ct:pal("0: Collected data ~p", [ExitStatus]),
- ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
- Other ->
- ct:fail(Other)
+ CompressAlgs = [zlib, '[email protected]',none],
+ case ssh_test_lib:ssh_supports(CompressAlgs, compression) of
+ {false,L} ->
+ {skip, io_lib:format("~p compression is not supported",[L])};
+
+ true ->
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {preferred_algorithms,
+ [{compression,CompressAlgs}]}]),
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+ success = ssh_connection:exec(ConnectionRef, ChannelId,
+ "echo testing", infinity),
+ Data = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(Data) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
+ {unexpected_msg,{ssh_cm, ConnectionRef,
+ {exit_status, ChannelId, 0}} = ExitStatus} ->
+ ct:log("0: Collected data ~p", [ExitStatus]),
+ ssh_test_lib:receive_exec_result(Data, ConnectionRef, ChannelId);
+ Other ->
+ ct:fail(Other)
+ end
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_cipher_suites() ->
- [{doc, "Test that we can connect with different cipher suites."}].
-
-erlang_server_openssh_client_cipher_suites(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Supports = crypto:supports(),
- Ciphers = proplists:get_value(ciphers, Supports),
- Tests = [
- {"3des-cbc", lists:member(des3_cbc, Ciphers)},
- {"aes128-cbc", lists:member(aes_cbc128, Ciphers)},
- {"aes128-ctr", lists:member(aes_ctr, Ciphers)},
- {"aes256-cbc", false}
- ],
- lists:foreach(fun({Cipher, Expect}) ->
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
- " -c " ++ Cipher ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- case Expect of
- true ->
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
- end;
- false ->
- receive
- {SshPort,{data, <<"no matching cipher found", _/binary>>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive no matching cipher message")
- end
- end
- end, Tests),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_macs() ->
- [{doc, "Test that we can connect with different MACs."}].
-
-erlang_server_openssh_client_macs(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
-
- ct:sleep(500),
-
- Supports = crypto:supports(),
- Hashs = proplists:get_value(hashs, Supports),
- MACs = [{"hmac-sha1", lists:member(sha, Hashs)},
- {"hmac-sha2-256", lists:member(sha256, Hashs)},
- {"hmac-md5-96", false},
- {"hmac-ripemd160", false}],
- lists:foreach(fun({MAC, Expect}) ->
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " " ++ Host ++ " " ++
- " -o MACs=" ++ MAC ++ " 1+1.",
-
- ct:pal("Cmd: ~p~n", [Cmd]),
-
- SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
-
- case Expect of
- true ->
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
- end;
- false ->
- receive
- {SshPort,{data, <<"no matching mac found", _/binary>>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive no matching mac message")
- end
- end
- end, MACs),
-
- ssh:stop_daemon(Pid).
-
-%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec_compressed() ->
- [{doc, "Test that exec command works."}].
-
-erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) ->
- SystemDir = ?config(data_dir, Config),
- PrivDir = ?config(priv_dir, Config),
- KnownHosts = filename:join(PrivDir, "known_hosts"),
-
- {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
- {compression, zlib},
- {failfun, fun ssh_test_lib:failfun/2}]),
-
- ct:sleep(500),
-
- Cmd = "ssh -p " ++ integer_to_list(Port) ++
- " -o UserKnownHostsFile=" ++ KnownHosts ++ " -C "++ Host ++ " 1+1.",
- SshPort = open_port({spawn, Cmd}, [binary]),
-
- receive
- {SshPort,{data, <<"2\n">>}} ->
- ok
- after ?TIMEOUT ->
- ct:fail("Did not receive answer")
-
- end,
- ssh:stop_daemon(Pid).
+erlang_client_openssh_server_kexs() ->
+ [{doc, "Test that we can connect with different KEXs."}].
+
+erlang_client_openssh_server_kexs(Config) when is_list(Config) ->
+ KexAlgos = try proplists:get_value(kex, ?config(common_algs,Config))
+ catch _:_ -> []
+ end,
+ comment(KexAlgos),
+ case KexAlgos of
+ [] -> {skip, "No common kex algorithms"};
+ _ ->
+ Success =
+ lists:foldl(
+ fun(Kex, Acc) ->
+ ConnectionRef =
+ ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
+ {user_interaction, false},
+ {preferred_algorithms,
+ [{kex,[Kex]}]}]),
+
+ {ok, ChannelId} =
+ ssh_connection:session_channel(ConnectionRef, infinity),
+ success =
+ ssh_connection:exec(ConnectionRef, ChannelId,
+ "echo testing", infinity),
+
+ ExpectedData = {ssh_cm, ConnectionRef, {data, ChannelId, 0, <<"testing\n">>}},
+ case ssh_test_lib:receive_exec_result(ExpectedData) of
+ expected ->
+ ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId),
+ Acc;
+ {unexpected_msg,{ssh_cm, ConnectionRef,
+ {exit_status, ChannelId, 0}} = ExitStatus} ->
+ ct:log("0: Collected data ~p", [ExitStatus]),
+ ssh_test_lib:receive_exec_result(ExpectedData, ConnectionRef, ChannelId),
+ Acc;
+ Other ->
+ ct:log("~p failed: ~p",[Kex,Other]),
+ false
+ end
+ end, true, KexAlgos),
+ case Success of
+ true ->
+ ok;
+ false ->
+ {fail, "Kex failed for one or more algos"}
+ end
+ end.
%%--------------------------------------------------------------------
erlang_client_openssh_server_setenv() ->
@@ -373,11 +293,11 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) ->
{data,0,1, UnxpectedData}}} ->
%% Some os may return things as
%% ENV_TEST: Undefined variable.\n"
- ct:pal("UnxpectedData: ~p", [UnxpectedData]),
+ ct:log("UnxpectedData: ~p", [UnxpectedData]),
ssh_test_lib:receive_exec_end(ConnectionRef, ChannelId);
{unexpected_msg,{ssh_cm, ConnectionRef, {exit_status, ChannelId, 0}}
= ExitStatus} ->
- ct:pal("0: Collected data ~p", [ExitStatus]),
+ ct:log("0: Collected data ~p", [ExitStatus]),
ssh_test_lib:receive_exec_result(Data,
ConnectionRef, ChannelId);
Other ->
@@ -419,31 +339,20 @@ erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) ->
erlang_client_openssh_server_publickey_dsa() ->
[{doc, "Validate using dsa publickey."}].
erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
- {ok,[[Home]]} = init:get_argument(home),
- KeyFile = filename:join(Home, ".ssh/id_dsa"),
- case file:read_file(KeyFile) of
- {ok, Pem} ->
- case public_key:pem_decode(Pem) of
- [{_,_, not_encrypted}] ->
- ConnectionRef =
- ssh_test_lib:connect(?SSH_DEFAULT_PORT,
- [{public_key_alg, ssh_dsa},
- {user_interaction, false},
- silently_accept_hosts]),
- {ok, Channel} =
- ssh_connection:session_channel(ConnectionRef, infinity),
- ok = ssh_connection:close(ConnectionRef, Channel),
- ok = ssh:close(ConnectionRef);
- _ ->
- {skip, {error, "Has pass phrase can not be used by automated test case"}}
- end;
- _ ->
- {skip, "no ~/.ssh/id_dsa"}
- end.
+ ConnectionRef =
+ ssh_test_lib:connect(?SSH_DEFAULT_PORT,
+ [{public_key_alg, ssh_dsa},
+ {user_interaction, false},
+ silently_accept_hosts]),
+ {ok, Channel} =
+ ssh_connection:session_channel(ConnectionRef, infinity),
+ ok = ssh_connection:close(ConnectionRef, Channel),
+ ok = ssh:close(ConnectionRef).
+
%%--------------------------------------------------------------------
-erlang_server_openssh_client_pulic_key_dsa() ->
+erlang_server_openssh_client_public_key_dsa() ->
[{doc, "Validate using dsa publickey."}].
-erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
+erlang_server_openssh_client_public_key_dsa(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
KnownHosts = filename:join(PrivDir, "known_hosts"),
@@ -451,21 +360,25 @@ erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{public_key_alg, ssh_dsa},
{failfun, fun ssh_test_lib:failfun/2}]),
-
+
ct:sleep(500),
Cmd = "ssh -p " ++ integer_to_list(Port) ++
" -o UserKnownHostsFile=" ++ KnownHosts ++
" " ++ Host ++ " 1+1.",
- SshPort = open_port({spawn, Cmd}, [binary]),
+ SshPort = open_port({spawn, Cmd}, [binary, stderr_to_stdout]),
receive
- {SshPort,{data, <<"2\n">>}} ->
+ {SshPort,{data, <<"2\n">>}} ->
ok
after ?TIMEOUT ->
- ct:fail("Did not receive answer")
+ receive
+ X -> ct:fail("Received: ~p",[X])
+ after 0 ->
+ ct:fail("Did not receive answer")
+ end
end,
- ssh:stop_daemon(Pid).
+ ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
erlang_client_openssh_server_password() ->
@@ -475,12 +388,12 @@ erlang_client_openssh_server_password(Config) when is_list(Config) ->
UserDir = ?config(data_dir, Config),
{error, Reason0} =
ssh:connect(any, ?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
- {user, "foo"},
- {password, "morot"},
- {user_interaction, false},
- {user_dir, UserDir}]),
+ {user, "foo"},
+ {password, "morot"},
+ {user_interaction, false},
+ {user_dir, UserDir}]),
- ct:pal("Test of user foo that does not exist. "
+ ct:log("Test of user foo that does not exist. "
"Error msg: ~p~n", [Reason0]),
User = string:strip(os:cmd("whoami"), right, $\n),
@@ -494,10 +407,10 @@ erlang_client_openssh_server_password(Config) when is_list(Config) ->
{password, "foo"},
{user_interaction, false},
{user_dir, UserDir}]),
- ct:pal("Test of wrong Pasword. "
+ ct:log("Test of wrong Pasword. "
"Error msg: ~p~n", [Reason1]);
_ ->
- ct:pal("Whoami failed reason: ~n", [])
+ ct:log("Whoami failed reason: ~n", [])
end.
%%--------------------------------------------------------------------
@@ -525,34 +438,41 @@ erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config)
receive_hej() ->
receive
<<"Hej", _binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
<<"Hej\n", _binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
<<"Hej\r\n", _/binary>> = Hej ->
- ct:pal("Expected result: ~p~n", [Hej]);
+ ct:log("Expected result: ~p~n", [Hej]);
Info ->
Lines = binary:split(Info, [<<"\r\n">>], [global]),
case lists:member(<<"Hej">>, Lines) of
true ->
- ct:pal("Expected result found in lines: ~p~n", [Lines]),
+ ct:log("Expected result found in lines: ~p~n", [Lines]),
ok;
false ->
- ct:pal("Extra info: ~p~n", [Info]),
+ ct:log("Extra info: ~p~n", [Info]),
receive_hej()
end
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end.
receive_logout() ->
receive
<<"logout">> ->
+ extra_logout(),
receive
<<"Connection closed">> ->
ok
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
end;
Info ->
- ct:pal("Extra info when logging out: ~p~n", [Info]),
+ ct:log("Extra info when logging out: ~p~n", [Info]),
receive_logout()
- end.
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
receive_normal_exit(Shell) ->
receive
@@ -562,29 +482,30 @@ receive_normal_exit(Shell) ->
receive_normal_exit(Shell);
Other ->
ct:fail({unexpected_msg, Other})
+ after
+ 30000 -> ct:fail("timeout ~p:~p",[?MODULE,?LINE])
+ end.
+
+extra_logout() ->
+ receive
+ <<"logout">> ->
+ ok
+ after 500 ->
+ ok
end.
-%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
%% Check if we have a "newer" ssh client that supports these test cases
-%%--------------------------------------------------------------------
check_ssh_client_support(Config) ->
- Port = open_port({spawn, "ssh -Q cipher"}, [exit_status, stderr_to_stdout]),
- case check_ssh_client_support2(Port) of
- 0 -> % exit status from command (0 == ok)
+ case ssh_test_lib:ssh_client_supports_Q() of
+ true ->
ssh:start(),
Config;
_ ->
{skip, "test case not supported by ssh client"}
end.
-check_ssh_client_support2(P) ->
- receive
- {P, {data, _A}} ->
- check_ssh_client_support2(P);
- {P, {exit_status, E}} ->
- E
- after 5000 ->
- ct:pal("Openssh command timed out ~n"),
- -1
- end.
+comment(AtomList) ->
+ ct:comment(
+ string:join(lists:map(fun erlang:atom_to_list/1, AtomList),
+ ", ")).
diff --git a/lib/ssh/test/ssh_trpt_test_lib.erl b/lib/ssh/test/ssh_trpt_test_lib.erl
new file mode 100644
index 0000000000..4269529ae8
--- /dev/null
+++ b/lib/ssh/test/ssh_trpt_test_lib.erl
@@ -0,0 +1,772 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+-module(ssh_trpt_test_lib).
+
+%%-compile(export_all).
+
+-export([exec/1, exec/2,
+ instantiate/2,
+ format_msg/1,
+ server_host_port/1
+ ]
+ ).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("ssh/src/ssh.hrl"). % ?UINT32, ?BYTE, #ssh{} ...
+-include_lib("ssh/src/ssh_transport.hrl").
+-include_lib("ssh/src/ssh_auth.hrl").
+
+%%%----------------------------------------------------------------
+-record(s, {
+ socket,
+ listen_socket,
+ opts = [],
+ timeout = 5000, % ms
+ seen_hello = false,
+ enc = <<>>,
+ ssh = #ssh{}, % #ssh{}
+ alg_neg = {undefined,undefined}, % {own_kexinit, peer_kexinit}
+ alg, % #alg{}
+ vars = dict:new(),
+ reply = [], % Some repy msgs are generated hidden in ssh_transport :[
+ prints = [],
+ return_value
+ }).
+
+-define(role(S), ((S#s.ssh)#ssh.role) ).
+
+
+server_host_port(S=#s{}) ->
+ {Host,Port} = ok(inet:sockname(S#s.listen_socket)),
+ {host(Host), Port}.
+
+
+%%% Options: {print_messages, false} true|detail
+%%% {print_seqnums,false} true
+%%% {print_ops,false} true
+
+exec(L) -> exec(L, #s{}).
+
+exec(L, S) when is_list(L) -> lists:foldl(fun exec/2, S, L);
+
+exec(Op, S0=#s{}) ->
+ S1 = init_op_traces(Op, S0),
+ try seqnum_trace(
+ op(Op, S1))
+ of
+ S = #s{} ->
+ case proplists:get_value(silent,S#s.opts) of
+ true -> ok;
+ _ -> print_traces(S)
+ end,
+ {ok,S}
+ catch
+ {fail,Reason,Se} ->
+ report_trace('', Reason, Se),
+ {error,{Op,Reason,Se}};
+
+ throw:Term ->
+ report_trace(throw, Term, S1),
+ throw(Term);
+
+ error:Error ->
+ report_trace(error, Error, S1),
+ error(Error);
+
+ exit:Exit ->
+ report_trace(exit, Exit, S1),
+ exit(Exit)
+ end;
+exec(Op, {ok,S=#s{}}) -> exec(Op, S);
+exec(_, Error) -> Error.
+
+
+%%%---- Server ops
+op(listen, S) when ?role(S) == undefined -> op({listen,0}, S);
+
+op({listen,Port}, S) when ?role(S) == undefined ->
+ S#s{listen_socket = ok(gen_tcp:listen(Port, mangle_opts([]))),
+ ssh = (S#s.ssh)#ssh{role=server}
+ };
+
+op({accept,Opts}, S) when ?role(S) == server ->
+ {ok,Socket} = gen_tcp:accept(S#s.listen_socket, S#s.timeout),
+ {Host,_Port} = ok(inet:sockname(Socket)),
+ S#s{socket = Socket,
+ ssh = init_ssh(server,Socket,[{host,host(Host)}|Opts]),
+ return_value = ok};
+
+%%%---- Client ops
+op({connect,Host,Port,Opts}, S) when ?role(S) == undefined ->
+ Socket = ok(gen_tcp:connect(host(Host), Port, mangle_opts([]))),
+ S#s{socket = Socket,
+ ssh = init_ssh(client, Socket, [{host,host(Host)}|Opts]),
+ return_value = ok};
+
+%%%---- ops for both client and server
+op(close_socket, S) ->
+ catch tcp_gen:close(S#s.socket),
+ catch tcp_gen:close(S#s.listen_socket),
+ S#s{socket = undefined,
+ listen_socket = undefined,
+ return_value = ok};
+
+op({set_options,Opts}, S) ->
+ S#s{opts = Opts};
+
+op({send,X}, S) ->
+ send(S, instantiate(X,S));
+
+op(receive_hello, S0) when S0#s.seen_hello =/= true ->
+ case recv(S0) of
+ S1=#s{return_value={hello,_}} -> S1;
+ S1=#s{} -> op(receive_hello, receive_wait(S1))
+ end;
+
+op(receive_msg, S) when S#s.seen_hello == true ->
+ try recv(S)
+ catch
+ {tcp,Exc} ->
+ S1 = opt(print_messages, S,
+ fun(X) when X==true;X==detail -> {"Recv~n~p~n",[Exc]} end),
+ S1#s{return_value=Exc}
+ end;
+
+
+op({expect,timeout,E}, S0) ->
+ try op(E, S0)
+ of
+ S=#s{} -> fail({expected,timeout,S#s.return_value}, S)
+ catch
+ {receive_timeout,_} -> S0#s{return_value=timeout}
+ end;
+
+op({match,M,E}, S0) ->
+ {Val,S2} = op_val(E, S0),
+ case match(M, Val, S2) of
+ {true,S3} ->
+ opt(print_ops,S3,
+ fun(true) ->
+ case dict:fold(
+ fun(K,V,Acc) ->
+ case dict:find(K,S0#s.vars) of
+ error -> [{K,V}|Acc];
+ _ -> Acc
+ end
+ end, [], S3#s.vars)
+ of
+ [] -> {"Matches! No new bindings.",[]};
+ New ->
+ Width = lists:max([length(atom_to_list(K)) || {K,_} <- New]),
+ {lists:flatten(
+ ["Matches! New bindings:~n" |
+ [io_lib:format(" ~*s = ~p~n",[Width,K,V]) || {K,V}<-New]]),
+ []}
+ end
+ end);
+ false ->
+ fail({expected,M,Val},
+ opt(print_ops,S2,fun(true) -> {"nomatch!!~n",[]} end)
+ )
+ end;
+
+op({print,E}, S0) ->
+ {Val,S} = op_val(E, S0),
+ io:format("Result of ~p ~p =~n~s~n",[?role(S0),E,format_msg(Val)]),
+ S;
+
+op(print_state, S) ->
+ io:format("State(~p)=~n~s~n",[?role(S), format_msg(S)]),
+ S;
+
+op('$$', S) ->
+ %% For matching etc
+ S.
+
+
+op_val(E, S0) ->
+ case catch op(E, S0) of
+ {'EXIT',{function_clause,[{ssh_trpt_test_lib,op,[E,S0],_}|_]}} ->
+ {instantiate(E,S0), S0};
+ S=#s{} ->
+ {S#s.return_value, S};
+ F={fail,receive_timeout,_St} ->
+ throw(F)
+ end.
+
+
+fail(Reason, {Fmt,Args}, S) when is_list(Fmt), is_list(Args) ->
+ fail(Reason, save_prints({Fmt,Args}, S)).
+
+fail(Reason, S) ->
+ throw({fail, Reason, S}).
+
+%%%----------------------------------------------------------------
+%% No optimizations :)
+
+match('$$', V, S) ->
+ match(S#s.return_value, V, S);
+
+match('_', _, S) ->
+ {true, S};
+
+match({'or',[P]}, V, S) -> match(P,V,S);
+match({'or',[Ph|Pt]}, V, S) ->
+ case match(Ph,V,S) of
+ false -> match({'or',Pt}, V, S);
+ {true,S} -> {true,S}
+ end;
+
+match(P, V, S) when is_atom(P) ->
+ case atom_to_list(P) of
+ "$"++_ ->
+ %% Variable
+ case dict:find(P,S#s.vars) of
+ {ok,Val} -> match(Val, V, S);
+ error -> {true,S#s{vars = dict:store(P,V,S#s.vars)}}
+ end;
+ _ when P==V ->
+ {true,S};
+ _ ->
+ false
+ end;
+
+match(P, V, S) when P==V ->
+ {true, S};
+
+match(P, V, S) when is_tuple(P),
+ is_tuple(V) ->
+ match(tuple_to_list(P), tuple_to_list(V), S);
+
+match([Hp|Tp], [Hv|Tv], S0) ->
+ case match(Hp, Hv, S0) of
+ {true,S} -> match(Tp, Tv, S);
+ false -> false
+ end;
+
+match(_, _, _) ->
+ false.
+
+
+
+instantiate('$$', S) ->
+ S#s.return_value; % FIXME: What if $$ or $... in return_value?
+
+instantiate(A, S) when is_atom(A) ->
+ case atom_to_list(A) of
+ "$"++_ ->
+ %% Variable
+ case dict:find(A,S#s.vars) of
+ {ok,Val} -> Val; % FIXME: What if $$ or $... in Val?
+ error -> throw({unbound,A})
+ end;
+ _ ->
+ A
+ end;
+
+instantiate(T, S) when is_tuple(T) ->
+ list_to_tuple( instantiate(tuple_to_list(T),S) );
+
+instantiate([H|T], S) ->
+ [instantiate(H,S) | instantiate(T,S)];
+
+instantiate(X, _S) ->
+ X.
+
+%%%================================================================
+%%%
+init_ssh(Role, Socket, Options0) ->
+ Options = [{user_interaction,false}
+ | Options0],
+ ssh_connection_handler:init_ssh(Role,
+ {2,0},
+ lists:concat(["SSH-2.0-ErlangTestLib ",Role]),
+ Options, Socket).
+
+mangle_opts(Options) ->
+ SysOpts = [{reuseaddr, true},
+ {active, false},
+ {mode, binary}
+ ],
+ SysOpts ++ lists:foldl(fun({K,_},Opts) ->
+ lists:keydelete(K,1,Opts)
+ end, Options, SysOpts).
+
+host({0,0,0,0}) -> "localhost";
+host(H) -> H.
+
+%%%----------------------------------------------------------------
+send(S=#s{ssh=C}, hello) ->
+ Hello = case ?role(S) of
+ client -> C#ssh.c_version;
+ server -> C#ssh.s_version
+ end ++ "\r\n",
+ send(S, list_to_binary(Hello));
+
+send(S0, ssh_msg_kexinit) ->
+ {Msg, _Bytes, _C0} = ssh_transport:key_exchange_init_msg(S0#s.ssh),
+ send(S0, Msg);
+
+send(S0=#s{alg_neg={undefined,PeerMsg}}, Msg=#ssh_msg_kexinit{}) ->
+ S1 = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ S2 = case PeerMsg of
+ #ssh_msg_kexinit{} ->
+ try ssh_transport:handle_kexinit_msg(PeerMsg, Msg, S1#s.ssh) of
+ {ok,Cx} when ?role(S1) == server ->
+ S1#s{alg = Cx#ssh.algorithms};
+ {ok,_NextKexMsgBin,Cx} when ?role(S1) == client ->
+ S1#s{alg = Cx#ssh.algorithms}
+ catch
+ Class:Exc ->
+ save_prints({"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s~n",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(Msg)]},
+ S1)
+ end;
+ undefined ->
+ S1
+ end,
+ {Bytes, C} = ssh_transport:ssh_packet(Msg, S2#s.ssh),
+ send_bytes(Bytes, S2#s{return_value = Msg,
+ alg_neg = {Msg,PeerMsg},
+ ssh = C});
+
+send(S0, ssh_msg_kexdh_init) when ?role(S0) == client ->
+ {OwnMsg, PeerMsg} = S0#s.alg_neg,
+ {ok, NextKexMsgBin, C} =
+ try ssh_transport:handle_kexinit_msg(PeerMsg, OwnMsg, S0#s.ssh)
+ catch
+ Class:Exc ->
+ fail("Algoritm negotiation failed!",
+ {"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(OwnMsg)]},
+ S0)
+ end,
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail ->
+ #ssh{keyex_key = {{_Private, Public}, {_G, _P}}} = C,
+ Msg = #ssh_msg_kexdh_init{e = Public},
+ {"Send (reconstructed)~n~s~n",[format_msg(Msg)]}
+ end),
+ send_bytes(NextKexMsgBin, S#s{ssh = C});
+
+send(S0, ssh_msg_kexdh_reply) ->
+ Bytes = proplists:get_value(ssh_msg_kexdh_reply, S0#s.reply),
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail ->
+ {{_Private, Public}, _} = (S0#s.ssh)#ssh.keyex_key,
+ Msg = #ssh_msg_kexdh_reply{public_host_key = 'Key',
+ f = Public,
+ h_sig = 'H_SIG'
+ },
+ {"Send (reconstructed)~n~s~n",[format_msg(Msg)]}
+ end),
+ send_bytes(Bytes, S#s{return_value = Bytes});
+
+send(S0, Line) when is_binary(Line) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send line~n~p~n",[Line]} end),
+ send_bytes(Line, S#s{return_value = Line});
+
+send(S0, {special,Msg,PacketFun}) when is_tuple(Msg),
+ is_function(PacketFun,2) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {Packet, C} = PacketFun(Msg, S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
+ return_value = Msg});
+
+send(S0, Msg) when is_tuple(Msg) ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Send~n~s~n",[format_msg(Msg)]} end),
+ {Packet, C} = ssh_transport:ssh_packet(Msg, S#s.ssh),
+ send_bytes(Packet, S#s{ssh = C, %%inc_send_seq_num(C),
+ return_value = Msg}).
+
+send_bytes(B, S0) ->
+ S = opt(print_messages, S0, fun(detail) -> {"Send bytes~n~p~n",[B]} end),
+ ok(gen_tcp:send(S#s.socket, B)),
+ S.
+
+%%%----------------------------------------------------------------
+recv(S0 = #s{}) ->
+ S1 = receive_poll(S0),
+ case S1#s.seen_hello of
+ {more,Seen} ->
+ %% Has received parts of a line. Has not seen a complete hello.
+ try_find_crlf(Seen, S1);
+ false ->
+ %% Must see hello before binary messages
+ try_find_crlf(<<>>, S1);
+ true ->
+ %% Has seen hello, therefore no more crlf-messages are alowed.
+ S = receive_binary_msg(S1),
+ case PeerMsg = S#s.return_value of
+ #ssh_msg_kexinit{} ->
+ case S#s.alg_neg of
+ {undefined,undefined} ->
+ S#s{alg_neg = {undefined,PeerMsg}};
+
+ {undefined,_} ->
+ fail("2 kexint received!!", S);
+
+ {OwnMsg, _} ->
+ try ssh_transport:handle_kexinit_msg(PeerMsg, OwnMsg, S#s.ssh) of
+ {ok,C} when ?role(S) == server ->
+ S#s{alg_neg = {OwnMsg, PeerMsg},
+ alg = C#ssh.algorithms,
+ ssh = C};
+ {ok,_NextKexMsgBin,C} when ?role(S) == client ->
+ S#s{alg_neg = {OwnMsg, PeerMsg},
+ alg = C#ssh.algorithms}
+ catch
+ Class:Exc ->
+ save_prints({"Algoritm negotiation failed at line ~p:~p~n~p:~s~nPeer: ~s~n Own: ~s~n",
+ [?MODULE,?LINE,Class,format_msg(Exc),format_msg(PeerMsg),format_msg(OwnMsg)]},
+ S#s{alg_neg = {OwnMsg, PeerMsg}})
+ end
+ end;
+
+ #ssh_msg_kexdh_init{} -> % Always the server
+ {ok, Reply, C} = ssh_transport:handle_kexdh_init(PeerMsg, S#s.ssh),
+ S#s{ssh = C,
+ reply = [{ssh_msg_kexdh_reply,Reply} | S#s.reply]
+ };
+ #ssh_msg_kexdh_reply{} ->
+ {ok, _NewKeys, C} = ssh_transport:handle_kexdh_reply(PeerMsg, S#s.ssh),
+ S#s{ssh=C#ssh{send_sequence=S#s.ssh#ssh.send_sequence}}; % Back the number
+ #ssh_msg_newkeys{} ->
+ {ok, C} = ssh_transport:handle_new_keys(PeerMsg, S#s.ssh),
+ S#s{ssh=C};
+ _ ->
+ S
+ end
+ end.
+
+%%%================================================================
+try_find_crlf(Seen, S0) ->
+ case erlang:decode_packet(line,S0#s.enc,[]) of
+ {more,_} ->
+ Line = <<Seen/binary,(S0#s.enc)/binary>>,
+ S0#s{seen_hello = {more,Line},
+ enc = <<>>, % didn't find a complete line
+ % -> no more characters to test
+ return_value = {more,Line}
+ };
+ {ok,Used,Rest} ->
+ Line = <<Seen/binary,Used/binary>>,
+ case handle_hello(Line, S0) of
+ false ->
+ S = opt(print_messages, S0,
+ fun(X) when X==true;X==detail -> {"Recv info~n~p~n",[Line]} end),
+ S#s{seen_hello = false,
+ enc = Rest,
+ return_value = {info,Line}};
+ S1=#s{} ->
+ S = opt(print_messages, S1,
+ fun(X) when X==true;X==detail -> {"Recv hello~n~p~n",[Line]} end),
+ S#s{seen_hello = true,
+ enc = Rest,
+ return_value = {hello,Line}}
+ end
+ end.
+
+
+handle_hello(Bin, S=#s{ssh=C}) ->
+ case {ssh_transport:handle_hello_version(binary_to_list(Bin)),
+ ?role(S)}
+ of
+ {{undefined,_}, _} -> false;
+ {{Vp,Vs}, client} -> S#s{ssh = C#ssh{s_vsn=Vp, s_version=Vs}};
+ {{Vp,Vs}, server} -> S#s{ssh = C#ssh{c_vsn=Vp, c_version=Vs}}
+ end.
+
+receive_binary_msg(S0=#s{ssh=C0=#ssh{decrypt_block_size = BlockSize,
+ recv_mac_size = MacSize
+ }
+ }) ->
+ case size(S0#s.enc) >= max(8,BlockSize) of
+ false ->
+ %% Need more bytes to decode the packet_length field
+ Remaining = max(8,BlockSize) - size(S0#s.enc),
+ receive_binary_msg( receive_wait(Remaining, S0) );
+ true ->
+ %% Has enough bytes to decode the packet_length field
+ {_, <<?UINT32(PacketLen), _/binary>>, _} =
+ ssh_transport:decrypt_blocks(S0#s.enc, BlockSize, C0), % FIXME: BlockSize should be at least 4
+
+ %% FIXME: Check that ((4+PacketLen) rem BlockSize) == 0 ?
+
+ S1 = if
+ PacketLen > ?SSH_MAX_PACKET_SIZE ->
+ fail({too_large_message,PacketLen},S0); % FIXME: disconnect
+
+ ((4+PacketLen) rem BlockSize) =/= 0 ->
+ fail(bad_packet_length_modulo, S0); % FIXME: disconnect
+
+ size(S0#s.enc) >= (4 + PacketLen + MacSize) ->
+ %% has the whole packet
+ S0;
+
+ true ->
+ %% need more bytes to get have the whole packet
+ Remaining = (4 + PacketLen + MacSize) - size(S0#s.enc),
+ receive_wait(Remaining, S0)
+ end,
+
+ %% Decrypt all, including the packet_length part (re-use the initial #ssh{})
+ {C1, SshPacket = <<?UINT32(_),?BYTE(PadLen),Tail/binary>>, EncRest} =
+ ssh_transport:decrypt_blocks(S1#s.enc, PacketLen+4, C0),
+
+ PayloadLen = PacketLen - 1 - PadLen,
+ <<CompressedPayload:PayloadLen/binary, _Padding:PadLen/binary>> = Tail,
+
+ {C2, Payload} = ssh_transport:decompress(C1, CompressedPayload),
+
+ <<Mac:MacSize/binary, Rest/binary>> = EncRest,
+
+ case {ssh_transport:is_valid_mac(Mac, SshPacket, C2),
+ catch ssh_message:decode(set_prefix_if_trouble(Payload,S1))}
+ of
+ {false, _} -> fail(bad_mac,S1);
+ {_, {'EXIT',_}} -> fail(decode_failed,S1);
+
+ {true, Msg} ->
+ C3 = case Msg of
+ #ssh_msg_kexinit{} ->
+ ssh_transport:key_init(opposite_role(C2), C2, Payload);
+ _ ->
+ C2
+ end,
+ S2 = opt(print_messages, S1,
+ fun(X) when X==true;X==detail -> {"Recv~n~s~n",[format_msg(Msg)]} end),
+ S3 = opt(print_messages, S2,
+ fun(detail) -> {"decrypted bytes ~p~n",[SshPacket]} end),
+ S3#s{ssh = inc_recv_seq_num(C3),
+ enc = Rest,
+ return_value = Msg
+ }
+ end
+ end.
+
+
+set_prefix_if_trouble(Msg = <<?BYTE(Op),_/binary>>, #s{alg=#alg{kex=Kex}})
+ when Op == 30;
+ Op == 31
+ ->
+ case catch atom_to_list(Kex) of
+ "ecdh-sha2-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
+ "diffie-hellman-group-exchange-" ++ _ ->
+ <<"dh_gex",Msg/binary>>;
+ "diffie-hellman-group" ++ _ ->
+ <<"dh",Msg/binary>>;
+ _ ->
+ Msg
+ end;
+set_prefix_if_trouble(Msg, _) ->
+ Msg.
+
+
+receive_poll(S=#s{socket=Sock}) ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ receive_poll( S#s{enc = <<(S#s.enc)/binary,Data/binary>>} );
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after 0 ->
+ S
+ end.
+
+receive_wait(S=#s{socket=Sock,
+ timeout=Timeout}) ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ S#s{enc = <<(S#s.enc)/binary,Data/binary>>};
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after Timeout ->
+ fail(receive_timeout,S)
+ end.
+
+receive_wait(N, S=#s{socket=Sock,
+ timeout=Timeout,
+ enc=Enc0}) when N>0 ->
+ inet:setopts(Sock, [{active,once}]),
+ receive
+ {tcp,Sock,Data} ->
+ receive_wait(N-size(Data), S#s{enc = <<Enc0/binary,Data/binary>>});
+ {tcp_closed,Sock} ->
+ throw({tcp,tcp_closed});
+ {tcp_error, Sock, Reason} ->
+ throw({tcp,{tcp_error,Reason}})
+ after Timeout ->
+ fail(receive_timeout, S)
+ end;
+receive_wait(_N, S) ->
+ S.
+
+%% random_padding_len(PaddingLen1, ChunkSize) ->
+%% MaxAdditionalRandomPaddingLen = % max 255 bytes padding totaö
+%% (255 - PaddingLen1) - ((255 - PaddingLen1) rem ChunkSize),
+%% AddLen0 = crypto:rand_uniform(0,MaxAdditionalRandomPaddingLen),
+%% AddLen0 - (AddLen0 rem ChunkSize). % preserve the blocking
+
+inc_recv_seq_num(C=#ssh{recv_sequence=N}) -> C#ssh{recv_sequence=(N+1) band 16#ffffffff}.
+%%%inc_send_seq_num(C=#ssh{send_sequence=N}) -> C#ssh{send_sequence=(N+1) band 16#ffffffff}.
+
+opposite_role(#ssh{role=R}) -> opposite_role(R);
+opposite_role(client) -> server;
+opposite_role(server) -> client.
+
+ok(ok) -> ok;
+ok({ok,R}) -> R;
+ok({error,E}) -> erlang:error(E).
+
+
+%%%================================================================
+%%%
+%%% Formating of records
+%%%
+
+format_msg(M) -> format_msg(M, 0).
+
+format_msg(M, I0) ->
+ case fields(M) of
+ undefined -> io_lib:format('~p',[M]);
+ Fields ->
+ [Name|Args] = tuple_to_list(M),
+ Head = io_lib:format('#~p{',[Name]),
+ I = lists:flatlength(Head)+I0,
+ NL = io_lib:format('~n~*c',[I,$ ]),
+ Sep = io_lib:format(',~n~*c',[I,$ ]),
+ Tail = [begin
+ S0 = io_lib:format('~p = ',[F]),
+ I1 = I + lists:flatlength(S0),
+ [S0,format_msg(A,I1)]
+ end
+ || {F,A} <- lists:zip(Fields,Args)],
+ [[Head|string:join(Tail,Sep)],NL,"}"]
+ end.
+
+fields(M) ->
+ case M of
+ #ssh_msg_debug{} -> record_info(fields, ssh_msg_debug);
+ #ssh_msg_disconnect{} -> record_info(fields, ssh_msg_disconnect);
+ #ssh_msg_ignore{} -> record_info(fields, ssh_msg_ignore);
+ #ssh_msg_kex_dh_gex_group{} -> record_info(fields, ssh_msg_kex_dh_gex_group);
+ #ssh_msg_kex_dh_gex_init{} -> record_info(fields, ssh_msg_kex_dh_gex_init);
+ #ssh_msg_kex_dh_gex_reply{} -> record_info(fields, ssh_msg_kex_dh_gex_reply);
+ #ssh_msg_kex_dh_gex_request{} -> record_info(fields, ssh_msg_kex_dh_gex_request);
+ #ssh_msg_kex_dh_gex_request_old{} -> record_info(fields, ssh_msg_kex_dh_gex_request_old);
+ #ssh_msg_kexdh_init{} -> record_info(fields, ssh_msg_kexdh_init);
+ #ssh_msg_kexdh_reply{} -> record_info(fields, ssh_msg_kexdh_reply);
+ #ssh_msg_kexinit{} -> record_info(fields, ssh_msg_kexinit);
+ #ssh_msg_newkeys{} -> record_info(fields, ssh_msg_newkeys);
+ #ssh_msg_service_accept{} -> record_info(fields, ssh_msg_service_accept);
+ #ssh_msg_service_request{} -> record_info(fields, ssh_msg_service_request);
+ #ssh_msg_unimplemented{} -> record_info(fields, ssh_msg_unimplemented);
+ #ssh_msg_userauth_request{} -> record_info(fields, ssh_msg_userauth_request);
+ #ssh_msg_userauth_failure{} -> record_info(fields, ssh_msg_userauth_failure);
+ #ssh_msg_userauth_success{} -> record_info(fields, ssh_msg_userauth_success);
+ #ssh_msg_userauth_banner{} -> record_info(fields, ssh_msg_userauth_banner);
+ #ssh_msg_userauth_passwd_changereq{} -> record_info(fields, ssh_msg_userauth_passwd_changereq);
+ #ssh_msg_userauth_pk_ok{} -> record_info(fields, ssh_msg_userauth_pk_ok);
+ #ssh_msg_userauth_info_request{} -> record_info(fields, ssh_msg_userauth_info_request);
+ #ssh_msg_userauth_info_response{} -> record_info(fields, ssh_msg_userauth_info_response);
+ #s{} -> record_info(fields, s);
+ #ssh{} -> record_info(fields, ssh);
+ #alg{} -> record_info(fields, alg);
+ _ -> undefined
+ end.
+
+%%%================================================================
+%%%
+%%% Trace handling
+%%%
+
+init_op_traces(Op, S0) ->
+ opt(print_ops, S0#s{prints=[]},
+ fun(true) ->
+ case ?role(S0) of
+ undefined -> {"-- ~p~n",[Op]};
+ Role -> {"-- ~p ~p~n",[Role,Op]}
+ end
+ end
+ ).
+
+report_trace(Class, Term, S) ->
+ print_traces(
+ opt(print_ops, S,
+ fun(true) -> {"~s ~p",[Class,Term]} end)
+ ).
+
+seqnum_trace(S) ->
+ opt(print_seqnums, S,
+ fun(true) when S#s.ssh#ssh.send_sequence =/= S#s.ssh#ssh.send_sequence,
+ S#s.ssh#ssh.recv_sequence =/= S#s.ssh#ssh.recv_sequence ->
+ {"~p seq num: send ~p->~p, recv ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.send_sequence, S#s.ssh#ssh.send_sequence,
+ S#s.ssh#ssh.recv_sequence, S#s.ssh#ssh.recv_sequence
+ ]};
+ (true) when S#s.ssh#ssh.send_sequence =/= S#s.ssh#ssh.send_sequence ->
+ {"~p seq num: send ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.send_sequence, S#s.ssh#ssh.send_sequence]};
+ (true) when S#s.ssh#ssh.recv_sequence =/= S#s.ssh#ssh.recv_sequence ->
+ {"~p seq num: recv ~p->~p~n",
+ [?role(S),
+ S#s.ssh#ssh.recv_sequence, S#s.ssh#ssh.recv_sequence]}
+ end).
+
+print_traces(S) when S#s.prints == [] -> S;
+print_traces(S) ->
+ Len = length(S#s.prints),
+ ct:log("~s",
+ [lists:foldl(
+ fun({Fmt,Args}, Acc) ->
+ [case Len-length(Acc)-1 of
+ 0 ->
+ io_lib:format(Fmt,Args);
+ _N ->
+ io_lib:format(lists:concat(['~p --------~n',Fmt]),
+ [Len-length(Acc)-1|Args])
+ end | Acc]
+ end, "", S#s.prints)]
+ ).
+
+opt(Flag, S, Fun) when is_function(Fun,1) ->
+ try Fun(proplists:get_value(Flag,S#s.opts))
+ of P={Fmt,Args} when is_list(Fmt), is_list(Args) ->
+ save_prints(P, S)
+ catch _:_ ->
+ S
+ end.
+
+save_prints({Fmt,Args}, S) ->
+ S#s{prints = [{Fmt,Args}|S#s.prints]}.
diff --git a/lib/ssh/test/ssh_unicode_SUITE.erl b/lib/ssh/test/ssh_unicode_SUITE.erl
deleted file mode 100644
index cc916673b3..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE.erl
+++ /dev/null
@@ -1,587 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2014. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-
-%% gerl +fnu
-%% ct:run_test([{suite,"ssh_unicode_SUITE"}, {logdir,"LOG"}]).
-
--module(ssh_unicode_SUITE).
-
-%% Note: This directive should only be used in test suites.
--compile(export_all).
-
--include_lib("common_test/include/ct.hrl").
--include_lib("kernel/include/file.hrl").
-
-% Default timetrap timeout
--define(default_timeout, ?t:minutes(1)).
-
--define(USER, "åke高兴").
--define(PASSWD, "ärlig日本じん").
--define('sftp.txt', "sftp瑞点.txt").
--define('test.txt', "testハンス.txt").
--define('link_test.txt', "link_test語.txt").
-
--define(bindata, unicode:characters_to_binary("foobar å 一二三四いちにさんち") ).
-
--define(NEWLINE, <<"\r\n">>).
-
-%%--------------------------------------------------------------------
-%% Common Test interface functions -----------------------------------
-%%--------------------------------------------------------------------
-
-%% suite() ->
-%% [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [{group, sftp},
- {group, shell}
- ].
-
-
-init_per_suite(Config) ->
- case {file:native_name_encoding(), (catch crypto:start())} of
- {utf8, ok} ->
- ssh:start(),
- Config;
- {utf8, _} ->
- {skip,"Could not start crypto!"};
- _ ->
- {skip,"Not unicode filename enabled emulator"}
- end.
-
-end_per_suite(Config) ->
- ssh:stop(),
- crypto:stop(),
- Config.
-
-%%--------------------------------------------------------------------
-groups() ->
- [{shell, [], [shell_no_unicode, shell_unicode_string]},
- {sftp, [], [open_close_file, open_close_dir, read_file, read_dir,
- write_file, rename_file, mk_rm_dir, remove_file, links,
- retrieve_attributes, set_attributes, async_read, async_read_bin,
- async_write
- %% , position, pos_read, pos_write
- ]}].
-
-init_per_group(Group, Config) when Group==sftp
- ; Group==shell ->
- PrivDir = ?config(priv_dir, Config),
- SysDir = ?config(data_dir, Config),
- Sftpd =
- ssh_test_lib:daemon([{system_dir, SysDir},
- {user_dir, PrivDir},
- {user_passwords, [{?USER, ?PASSWD}]}]),
- [{group,Group}, {sftpd, Sftpd} | Config];
-
-init_per_group(Group, Config) ->
- [{group,Group} | Config].
-
-
-end_per_group(erlang_server, Config) ->
- Config;
-end_per_group(_, Config) ->
- Config.
-
-%%--------------------------------------------------------------------
-init_per_testcase(_Case, Config) ->
- prep(Config),
- TmpConfig0 = lists:keydelete(watchdog, 1, Config),
- TmpConfig = lists:keydelete(sftp, 1, TmpConfig0),
- Dog = ct:timetrap(?default_timeout),
-
- case ?config(group, Config) of
- sftp ->
- {_Pid, Host, Port} = ?config(sftpd, Config),
- {ok, ChannelPid, Connection} =
- ssh_sftp:start_channel(Host, Port,
- [{user, ?USER},
- {password, ?PASSWD},
- {user_interaction, false},
- {silently_accept_hosts, true}]),
- Sftp = {ChannelPid, Connection},
- [{sftp, Sftp}, {watchdog, Dog} | TmpConfig];
- shell ->
- UserDir = ?config(priv_dir, Config),
- process_flag(trap_exit, true),
- {_Pid, _Host, Port} = ?config(sftpd, Config),
- ct:sleep(500),
- IO = ssh_test_lib:start_io_server(),
- Shell = ssh_test_lib:start_shell(Port, IO, UserDir,
- [{silently_accept_hosts, true},
- {user,?USER},{password,?PASSWD}]),
-%%ct:pal("IO=~p, Shell=~p, self()=~p",[IO,Shell,self()]),
- wait_for_erlang_first_line([{io,IO}, {shell,Shell} | Config])
- end.
-
-
-wait_for_erlang_first_line(Config) ->
- receive
- {'EXIT', _, _} ->
- {fail,no_ssh_connection};
- <<"Eshell ",_/binary>> = ErlShellStart ->
-%% ct:pal("Erlang shell start: ~p~n", [ErlShellStart]),
- Config;
- Other ->
- ct:pal("Unexpected answer from ssh server: ~p",[Other]),
- {fail,unexpected_answer}
- after 10000 ->
- ct:pal("No answer from ssh-server"),
- {fail,timeout}
- end.
-
-
-
-end_per_testcase(rename_file, Config) ->
- PrivDir = ?config(priv_dir, Config),
- NewFileName = filename:join(PrivDir, ?'test.txt'),
- file:delete(NewFileName),
- end_per_testcase(Config);
-end_per_testcase(_TC, Config) ->
- end_per_testcase(Config).
-
-end_per_testcase(Config) ->
- catch exit(?config(shell,Config), kill),
- case ?config(sftp, Config) of
- {Sftp, Connection} ->
- ssh_sftp:stop_channel(Sftp),
- ssh:close(Connection);
- _ ->
- ok
- end.
-
-%%--------------------------------------------------------------------
-%% Test Cases --------------------------------------------------------
-
--define(chk_expected(Received,Expected),
- (fun(R_,E_) when R_==E_ -> ok;
- (R_,E_) -> ct:pal("Expected: ~p~nReceived: ~p~n", [E_,R_]),
- E_ = R_
- end)(Received,Expected)).
-
--define(receive_chk(Ref,Expected),
- (fun(E__) ->
- receive
- {async_reply, Ref, Received} when Received==E__ ->
- ?chk_expected(Received, E__);
- {async_reply, Ref, Received} when Received=/=E__ ->
- ct:pal("Expected: ~p~nReceived: ~p~n", [E__,Received]),
- E__ = Received;
- Msg ->
- ct:pal("Expected (Ref=~p): ~p", [Ref,E__]),
- ct:fail(Msg)
- end
- end)(Expected)).
-
-%%--------------------------------------------------------------------
-
-
-open_close_file() ->
- [{doc, "Test API functions open/3 and close/2"}].
-open_close_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- lists:foreach(
- fun(Mode) ->
- ct:log("Mode: ~p",[Mode]),
- %% list_dir(PrivDir),
- ok = open_close_file(Sftp, FileName, Mode)
- end,
- [
- [read],
- [write],
- [write, creat],
- [write, trunc],
- [append],
- [read, binary]
- ]).
-
-open_close_file(Server, File, Mode) ->
- {ok, Handle} = ssh_sftp:open(Server, File, Mode),
- ok = ssh_sftp:close(Server, Handle).
-
-%%--------------------------------------------------------------------
-open_close_dir() ->
- [{doc, "Test API functions opendir/2 and close/2"}].
-open_close_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
-
- {ok, Handle} = ssh_sftp:opendir(Sftp, PrivDir),
- ok = ssh_sftp:close(Sftp, Handle),
- {error, _} = ssh_sftp:opendir(Sftp, FileName).
-
-%%--------------------------------------------------------------------
-read_file() ->
- [{doc, "Test API funtion read_file/2"}].
-read_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
- ?chk_expected(ssh_sftp:read_file(Sftp,FileName), file:read_file(FileName)).
-
-%%--------------------------------------------------------------------
-read_dir() ->
- [{doc,"Test API function list_dir/2"}].
-read_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("sftp list dir: ~ts~n", [Files]).
-
-%%--------------------------------------------------------------------
-write_file() ->
- [{doc, "Test API function write_file/2"}].
-write_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
- ok = ssh_sftp:write_file(Sftp, FileName, [?bindata]),
- ?chk_expected(file:read_file(FileName), {ok,?bindata}).
-
-%%--------------------------------------------------------------------
-remove_file() ->
- [{doc,"Test API function delete/2"}].
-remove_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- true = lists:member(filename:basename(FileName), Files),
- ok = ssh_sftp:delete(Sftp, FileName),
- {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- false = lists:member(filename:basename(FileName), NewFiles),
- {error, _} = ssh_sftp:delete(Sftp, FileName).
-%%--------------------------------------------------------------------
-rename_file() ->
- [{doc, "Test API function rename_file/2"}].
-rename_file(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- NewFileName = filename:join(PrivDir, ?'test.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok, Files} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~ts~nFiles: ~ts~n", [FileName, [[$\n,$ ,F]||F<-Files] ]),
- true = lists:member(filename:basename(FileName), Files),
- false = lists:member(filename:basename(NewFileName), Files),
- ok = ssh_sftp:rename(Sftp, FileName, NewFileName),
- {ok, NewFiles} = ssh_sftp:list_dir(Sftp, PrivDir),
- ct:pal("FileName: ~ts, Files: ~ts~n", [FileName, [[$\n,F]||F<-NewFiles] ]),
-
- false = lists:member(filename:basename(FileName), NewFiles),
- true = lists:member(filename:basename(NewFileName), NewFiles).
-
-%%--------------------------------------------------------------------
-mk_rm_dir() ->
- [{doc,"Test API functions make_dir/2, del_dir/2"}].
-mk_rm_dir(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- {Sftp, _} = ?config(sftp, Config),
-
- DirName = filename:join(PrivDir, "test"),
- ok = ssh_sftp:make_dir(Sftp, DirName),
- ok = ssh_sftp:del_dir(Sftp, DirName),
- NewDirName = filename:join(PrivDir, "foo/bar"),
- {error, _} = ssh_sftp:make_dir(Sftp, NewDirName),
- {error, _} = ssh_sftp:del_dir(Sftp, PrivDir).
-
-%%--------------------------------------------------------------------
-links() ->
- [{doc,"Tests API function make_symlink/3"}].
-links(Config) when is_list(Config) ->
- case os:type() of
- {win32, _} ->
- {skip, "Links are not fully supported by windows"};
- _ ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- LinkFileName = filename:join(PrivDir, ?'link_test.txt'),
-
- ok = ssh_sftp:make_symlink(Sftp, LinkFileName, FileName),
- {ok, FileName} = ssh_sftp:read_link(Sftp, LinkFileName)
- end.
-
-%%--------------------------------------------------------------------
-retrieve_attributes() ->
- [{doc, "Test API function read_file_info/3"}].
-retrieve_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok, FileInfo} = ssh_sftp:read_file_info(Sftp, FileName),
- {ok, NewFileInfo} = file:read_file_info(FileName),
-
- %% TODO comparison. There are some differences now is that ok?
- ct:pal("SFTP: ~p~nFILE: ~p~n", [FileInfo, NewFileInfo]).
-
-%%--------------------------------------------------------------------
-set_attributes() ->
- [{doc,"Test API function write_file_info/3"}].
-set_attributes(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
-
- {Sftp, _} = ?config(sftp, Config),
- {ok,Fd} = file:open(FileName, write),
- io:put_chars(Fd,"foo"),
- ok = ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#400}),
- {error, eacces} = file:write_file(FileName, "hello again"),
- ssh_sftp:write_file_info(Sftp, FileName, #file_info{mode=8#600}),
- ok = file:write_file(FileName, "hello again").
-
-%%--------------------------------------------------------------------
-
-async_read() ->
- [{doc,"Test API aread/3"}].
-async_read(Config) when is_list(Config) ->
- do_async_read(Config, false).
-
-async_read_bin() ->
- [{doc,"Test API aread/3"}].
-async_read_bin(Config) when is_list(Config) ->
- do_async_read(Config, true).
-
-do_async_read(Config, BinaryFlag) ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'sftp.txt'),
- {ok,ExpDataBin} = file:read_file(FileName),
- ExpData = case BinaryFlag of
- true -> ExpDataBin;
- false -> binary_to_list(ExpDataBin)
- end,
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read|case BinaryFlag of
- true -> [binary];
- false -> []
- end]),
- {async, Ref} = ssh_sftp:aread(Sftp, Handle, 20),
- ?receive_chk(Ref, {ok,ExpData}).
-
-%%--------------------------------------------------------------------
-async_write() ->
- [{doc,"Test API awrite/3"}].
-async_write(Config) when is_list(Config) ->
- {Sftp, _} = ?config(sftp, Config),
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
- Expected = ?bindata,
- {async, Ref} = ssh_sftp:awrite(Sftp, Handle, Expected),
-
- receive
- {async_reply, Ref, ok} ->
- {ok, Data} = file:read_file(FileName),
- ?chk_expected(Data, Expected);
- Msg ->
- ct:fail(Msg)
- end.
-
-%%--------------------------------------------------------------------
-
-position() ->
- [{doc, "Test API functions position/3"}].
-position(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- Data = list_to_binary("1234567890"),
- ssh_sftp:write_file(Sftp, FileName, [Data]),
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
-
- {ok, 3} = ssh_sftp:position(Sftp, Handle, {bof, 3}),
- {ok, "4"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 10} = ssh_sftp:position(Sftp, Handle, eof),
- eof = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 6} = ssh_sftp:position(Sftp, Handle, {bof, 6}),
- {ok, "7"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 9} = ssh_sftp:position(Sftp, Handle, {cur, 2}),
- {ok, "0"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 0} = ssh_sftp:position(Sftp, Handle, bof),
- {ok, "1"} = ssh_sftp:read(Sftp, Handle, 1),
-
- {ok, 1} = ssh_sftp:position(Sftp, Handle, cur),
- {ok, "2"} = ssh_sftp:read(Sftp, Handle, 1).
-
-%%--------------------------------------------------------------------
-pos_read() ->
- [{doc,"Test API functions pread/3 and apread/3"}].
-pos_read(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
- Data = ?bindata,
- ssh_sftp:write_file(Sftp, FileName, [Data]),
-
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [read]),
- {async, Ref} = ssh_sftp:apread(Sftp, Handle, {bof,5}, 4),
-
- ?receive_chk(Ref, {ok,binary_part(Data,5,4)}),
- ?chk_expected(ssh_sftp:pread(Sftp,Handle,{bof,4},4), {ok,binary_part(Data,4,4)}).
-
-
-%%--------------------------------------------------------------------
-pos_write() ->
- [{doc,"Test API functions pwrite/4 and apwrite/4"}].
-pos_write(Config) when is_list(Config) ->
- PrivDir = ?config(priv_dir, Config),
- FileName = filename:join(PrivDir, ?'test.txt'),
- {Sftp, _} = ?config(sftp, Config),
-
- {ok, Handle} = ssh_sftp:open(Sftp, FileName, [write]),
-
- Data = unicode:characters_to_list("再见"),
- ssh_sftp:write_file(Sftp, FileName, [Data]),
-
- NewData = unicode:characters_to_list(" さようなら"),
- {async, Ref} = ssh_sftp:apwrite(Sftp, Handle, {bof, 2}, NewData),
- ?receive_chk(Ref, ok),
-
- ok = ssh_sftp:pwrite(Sftp, Handle, eof, unicode:characters_to_list(" adjö ")),
-
- ?chk_expected(ssh_sftp:read_file(Sftp,FileName),
- {ok,unicode:characters_to_binary("再见 さようなら adjö ")}).
-
-%%--------------------------------------------------------------------
-sftp_nonexistent_subsystem() ->
- [{doc, "Try to execute sftp subsystem on a server that does not support it"}].
-sftp_nonexistent_subsystem(Config) when is_list(Config) ->
- {_,Host, Port} = ?config(sftpd, Config),
- {error,"server failed to start sftp subsystem"} =
- ssh_sftp:start_channel(Host, Port,
- [{user_interaction, false},
- {user, ?USER},
- {password, ?PASSWD},
- {silently_accept_hosts, true}]).
-
-%%--------------------------------------------------------------------
-shell_no_unicode(Config) ->
- do_shell(?config(io,Config),
- [new_prompt,
- {type,"io:format(\"hej ~p~n\",[42])."},
- {expect,"hej 42"}
- ]).
-
-%%--------------------------------------------------------------------
-shell_unicode_string(Config) ->
- do_shell(?config(io,Config),
- [new_prompt,
- {type,"io:format(\"こにちわ~ts~n\",[\"四二\"])."},
- {expect,"こにちわ四二"},
- {expect,"ok"}
- ]).
-
-%%--------------------------------------------------------------------
-%% Internal functions ------------------------------------------------
-%%--------------------------------------------------------------------
-prep(Config) ->
- PrivDir = ?config(priv_dir, Config),
- TestFile = filename:join(PrivDir, ?'sftp.txt'),
- TestFile1 = filename:join(PrivDir, ?'test.txt'),
- TestLink = filename:join(PrivDir, ?'link_test.txt'),
-
- file:delete(TestFile),
- file:delete(TestFile1),
- file:delete(TestLink),
-
- %% Initial config
- DataDir = ?config(data_dir, Config),
- FileName = filename:join(DataDir, ?'sftp.txt'),
- {ok,_BytesCopied} = file:copy(FileName, TestFile),
- Mode = 8#00400 bor 8#00200 bor 8#00040, % read & write owner, read group
- {ok, FileInfo} = file:read_file_info(TestFile),
- ok = file:write_file_info(TestFile,
- FileInfo#file_info{mode = Mode}).
-
-
-%% list_dir(Dir) ->
-%% ct:pal("prep/1: ls(~p):~n~p~n~ts",[Dir, file:list_dir(Dir),
-%% begin
-%% {ok,DL} = file:list_dir(Dir),
-%% [[$\n|FN] || FN <- DL]
-%% end]).
-
-
-%%--------------------------------------------------------------------
-do_shell(IO, List) -> do_shell(IO, 0, List).
-
-do_shell(IO, N, [new_prompt|More]) ->
- do_shell(IO, N+1, More);
-
-do_shell(IO, N, Ops=[{Order,Arg}|More]) ->
- receive
- X = <<"\r\n">> ->
-%% ct:pal("Skip newline ~p",[X]),
- do_shell(IO, N, Ops);
-
- <<P1,"> ">> when (P1-$0)==N ->
- do_shell_prompt(IO, N, Order, Arg, More);
-
- <<P1,P2,"> ">> when (P1-$0)*10 + (P2-$0) == N ->
- do_shell_prompt(IO, N, Order, Arg, More);
-
- Err when element(1,Err)==error ->
- ct:fail("do_shell error: ~p~n",[Err]);
-
- RecBin when Order==expect ; Order==expect_echo ->
-%% ct:pal("received ~p",[RecBin]),
- RecStr = string:strip(unicode:characters_to_list(RecBin)),
- ExpStr = string:strip(Arg),
- case lists:prefix(ExpStr, RecStr) of
- true when Order==expect ->
- ct:pal("Matched ~ts",[RecStr]),
- do_shell(IO, N, More);
- true when Order==expect_echo ->
- ct:pal("Matched echo ~ts",[RecStr]),
- do_shell(IO, N, More);
- false ->
- ct:fail("*** Expected ~p, but got ~p",[string:strip(ExpStr),RecStr])
- end
- after 10000 ->
- case Order of
- expect -> ct:fail("timeout, expected ~p",[string:strip(Arg)]);
- type -> ct:fail("timeout, no prompt")
- end
- end;
-
-do_shell(_, _, []) ->
- ok.
-
-
-do_shell_prompt(IO, N, type, Str, More) ->
-%% ct:pal("Matched prompt ~p to trigger sending of next line to server",[N]),
- IO ! {input, self(), Str++"\r\n"},
- ct:pal("Promt '~p> ', Sent ~ts",[N,Str++"\r\n"]),
- do_shell(IO, N, [{expect_echo,Str}|More]); % expect echo of the sent line
-do_shell_prompt(IO, N, Op, Str, More) ->
-%% ct:pal("Matched prompt ~p",[N]),
- do_shell(IO, N, [{Op,Str}|More]).
-
-%%--------------------------------------------------------------------
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt b/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt
deleted file mode 100644
index 3eaaddca21..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE_data/sftp.txt
+++ /dev/null
@@ -1 +0,0 @@
-åäöÅÄÖ瑞語
diff --git a/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt b/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt
deleted file mode 100644
index 3eaaddca21..0000000000
--- a/lib/ssh/test/ssh_unicode_SUITE_data/sftp瑞点.txt
+++ /dev/null
@@ -1 +0,0 @@
-åäöÅÄÖ瑞語
diff --git a/lib/ssh/test/ssh_upgrade_SUITE.erl b/lib/ssh/test/ssh_upgrade_SUITE.erl
new file mode 100644
index 0000000000..85f4d36258
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE.erl
@@ -0,0 +1,207 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014-2015. All Rights Reserved.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(ssh_upgrade_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+
+-record(state, {
+ config,
+ root_dir,
+ server,
+ client,
+ connection,
+ soft
+ }).
+
+
+%%%================================================================
+%%%
+%%% CommonTest callbacks
+%%%
+all() ->
+ [
+ minor_upgrade,
+ major_upgrade
+ ].
+
+init_per_suite(Config0) ->
+ catch crypto:stop(),
+ try {crypto:start(), erlang:system_info({wordsize, internal}) ==
+ erlang:system_info({wordsize, external})} of
+ {ok, true} ->
+ case ct_release_test:init(Config0) of
+ {skip, Reason} ->
+ {skip, Reason};
+ Config ->
+ ssh:start(),
+ Config
+ end;
+ {ok, false} ->
+ {skip, "Test server will not handle halfwordemulator correctly. Skip as halfwordemulator is deprecated"}
+ catch _:_ ->
+ {skip, "Crypto did not start"}
+ end.
+
+end_per_suite(Config) ->
+ ct_release_test:cleanup(Config),
+ ssh:stop(),
+ crypto:stop(),
+ UserDir = ?config(priv_dir, Config),
+ ssh_test_lib:clean_rsa(UserDir).
+
+init_per_testcase(_TestCase, Config) ->
+ Config.
+end_per_testcase(_TestCase, Config) ->
+ Config.
+
+%%%================================================================
+%%%
+%%% Test cases
+%%%
+major_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssh, major,{?MODULE, #state{config = Config}}, Config).
+
+minor_upgrade(Config) when is_list(Config) ->
+ ct_release_test:upgrade(ssh, minor,{?MODULE, #state{config = Config}}, Config).
+
+%%%================================================================
+%%%
+%%% ct_release_test callbacks
+%%%
+
+%%%----------------------------------------------------------------
+%%% Initialyze system before upgrade test starts.
+%%% Called by ct_release_test:upgrade/4
+upgrade_init(CTData, State) ->
+ {ok, AppUp={_, _, Up, _Down}} = ct_release_test:get_appup(CTData, ssh),
+ ct:log("AppUp: ~p", [AppUp]),
+ ct:log("Up: ~p", [Up]),
+ case Soft = is_soft(Up) of
+ %% It is symmetrical, if upgrade is soft so is downgrade
+ true ->
+ setup_server_client(State#state{soft = Soft});
+ false ->
+ State#state{soft = Soft}
+ end.
+
+%%%----------------------------------------------------------------
+%%% Check that upgrade was successful
+%%% Called by ct_release_test:upgrade/4
+upgrade_upgraded(_, #state{soft=false} = State) ->
+ test_hard(State, "upgrade");
+
+upgrade_upgraded(_, State) ->
+ test_soft(State, "upgrade1").
+
+%%%----------------------------------------------------------------
+%%% Check that downgrade was successful.
+%%% Called by ct_release_test:upgrade/4
+upgrade_downgraded(_, #state{soft=false} = State) ->
+ test_hard(State, "downgrade");
+
+upgrade_downgraded(_, #state{soft=true} = State) ->
+ test_soft(State, "downgrade1").
+
+%%%================================================================
+%%%
+%%% Private functions
+%%%
+
+is_soft([{restart_application, ssh}]) ->
+ false;
+is_soft(_) ->
+ true.
+
+
+test_hard(State0, FileName) ->
+ ct:log("test_hard State0=~p, FileName=~p",[State0, FileName]),
+ State = setup_server_client(State0),
+ test_connection(FileName, random_contents(), State).
+
+test_soft(State0, FileName) ->
+ ct:log("test_soft State0=~p, FileName=~p",[State0, FileName]),
+ State = test_connection(FileName, random_contents(), State0),
+ setup_server_client( close(State) ).
+
+
+setup_server_client(#state{config=Config} = State) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ FtpRootDir = filename:join(PrivDir, "ftp_root"),
+ catch file:make_dir(FtpRootDir),
+
+ SFTP = ssh_sftpd:subsystem_spec([{root,FtpRootDir},{cwd,FtpRootDir}]),
+
+ {Server,Host,Port} = ssh_test_lib:daemon([{system_dir,DataDir},
+ {user_passwords,[{"hej","hopp"}]},
+ {subsystems,[SFTP]}]),
+
+ {ok, ChannelPid, Connection} =
+ ssh_sftp:start_channel(Host, Port, [{user_interaction,false},
+ {silently_accept_hosts,true},
+ {user_dir,DataDir},
+ {user,"hej"},
+ {password,"hopp"}]),
+ State#state{server = Server,
+ client = ChannelPid,
+ connection = Connection}.
+
+
+test_connection(FileName, FileContents,
+ #state{client = ChannelPid,
+ root_dir = FtpRootDir} = State) ->
+ ct:log("test_connection Writing with ssh_sftp:write_file",[]),
+ case ssh_sftp:write_file(ChannelPid, FileName, FileContents) of
+ ok ->
+ case ssh_sftp:read_file(ChannelPid, FileName) of
+ {ok,FileContents} ->
+ State;
+ {ok,Unexpected} ->
+ ct:fail("Expected ~p but got ~p from sftp:read_file(~p,..) in RootDir ~p",
+ [FileContents,Unexpected,FileName,FtpRootDir]
+ );
+ Other ->
+ ct:fail("ssh_sftp:read_file(~p,~p) -> ~p~n"
+ "ssh_sftp:list_dir(~p,\".\") -> ~p",
+ [ChannelPid,FileName,Other,
+ ChannelPid, catch ssh_sftp:list_dir(ChannelPid, ".")])
+ end;
+
+ Other ->
+ ct:fail("ssh_sftp:write_file(~p,~p,~p) -> ~p",[ChannelPid,FileName,FileContents,Other])
+ end.
+
+
+close(#state{server = Server,
+ connection = Connection} = State) ->
+ ssh:close(Connection),
+ ssh:stop_daemon(Server),
+ State#state{server = undefined,
+ client = undefined,
+ connection = undefined}.
+
+
+random_contents() -> list_to_binary( random_chars(3) ).
+
+random_chars(N) -> [crypto:rand_uniform($a,$z) || _<-lists:duplicate(N,x)].
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa b/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa
new file mode 100644
index 0000000000..d306f8b26e
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/id_dsa
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBvAIBAAKBgQDfi2flSTZZofwT4yQT0NikX/LGNT7UPeB/XEWe/xovEYCElfaQ
+APFixXvEgXwoojmZ5kiQRKzLM39wBP0jPERLbnZXfOOD0PDnw0haMh7dD7XKVMod
+/EigVgHf/qBdM2M8yz1s/rRF7n1UpLSypziKjkzCm7JoSQ2zbWIPdmBIXwIVAMgP
+kpr7Sq3O7sHdb8D601DRjoExAoGAMOQxDfB2Fd8ouz6G96f/UOzRMI/Kdv8kYYKW
+JIGY+pRYrLPyYzUeJznwZreOJgrczAX+luHnKFWJ2Dnk5CyeXk67Wsr7pJ/4MBMD
+OKeIS0S8qoSBN8+Krp79fgA+yS3IfqbkJLtLu4EBaCX4mKQIX4++k44d4U5lc8pt
++9hlEI8CgYEAznKxx9kyC6bVo7LUYKaGhofRFt0SYFc5PVmT2VUGRs1R6+6DPD+e
+uEO6IhFct7JFSRbP9p0JD4Uk+3zlZF+XX6b2PsZkeV8f/02xlNGUSmEzCSiNg1AX
+Cy/WusYhul0MncWCHMcOZB5rIvU/aP5EJJtn3xrRaz6u0SThF6AnT34CFQC63czE
+ZU8w8Q+H7z0j+a+70x2iAw==
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa b/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa
new file mode 100644
index 0000000000..9d7e0dd5fb
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/id_rsa
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQD1OET+3O/Bvj/dtjxDTXmj1oiJt4sIph5kGy0RfjoPrZfaS+CU
+DhakCmS6t2ivxWFgtpKWaoGMZMJqWj6F6ZsumyFl3FPBtujwY/35cgifrI9Ns4Tl
+zR1uuengNBmV+WRQ5cd9F2qS6Z8aDQihzt0r8JUqLcK+VQbrmNzboCCQQwIDAQAB
+AoGAPQEyqPTt8JUT7mRXuaacjFXiweAXhp9NEDpyi9eLOjtFe9lElZCrsUOkq47V
+TGUeRKEm9qSodfTbKPoqc8YaBJGJPhUaTAcha+7QcDdfHBvIsgxvU7ePVnlpXRp3
+CCUEMPhlnx6xBoTYP+fRU0e3+xJIPVyVCqX1jAdUMkzfRoECQQD6ux7B1QJAIWyK
+SGkbDUbBilNmzCFNgIpOP6PA+bwfi5d16diTpra5AX09keQABAo/KaP1PdV8Vg0p
+z4P3A7G3AkEA+l+AKG6m0kQTTBMJDqOdVPYwe+5GxunMaqmhokpEbuGsrZBl5Dvd
+WpcBjR7jmenrhKZRIuA+Fz5HPo/UQJPl1QJBAKxstDkeED8j/S2XoFhPKAJ+6t39
+sUVICVTIZQeXdmzHJXCcUSkw8+WEhakqw/3SyW0oaK2FSWQJFWJUZ+8eJj8CQEh3
+xeduB5kKnS9CvzdeghZqX6QvVosSdtlUmfUYW/BgH5PpHKTP8wTaeld3XldZTpMJ
+dKiMkUw2+XYROVUrubUCQD+Na1LhULlpn4ISEtIEfqpdlUhxDgO15Wg8USmsng+x
+ICliVOSQtwaZjm8kwaFt0W7XnpnDxbRs37vIEbIMWak=
+-----END RSA PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts b/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/known_hosts
@@ -0,0 +1 @@
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key
new file mode 100644
index 0000000000..51ab6fbd88
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key
@@ -0,0 +1,13 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQCClaHzE2ul0gKSUxah5W0W8UiJLy4hXngKEqpaUq9SSdVdY2LK
+wVfKH1gt5iuaf1FfzOhsIC9G/GLnjYttXZc92cv/Gfe3gR+s0ni2++MX+T++mE/Q
+diltXv/Hp27PybS67SmiFW7I+RWnT2OKlMPtw2oUuKeztCe5UWjaj/y5FQIVAPLA
+l9RpiU30Z87NRAHY3NTRaqtrAoGANMRxw8UfdtNVR0CrQj3AgPaXOGE4d+G4Gp4X
+skvnCHycSVAjtYxebUkzUzt5Q6f/IabuLUdge3gXrc8BetvrcKbp+XZgM0/Vj2CF
+Ymmy3in6kzGZq7Fw1sZaku6AOU8vLa5woBT2vAcHLLT1bLAzj7viL048T6MfjrOP
+ef8nHvACgYBhDWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah
+/XcF3DeRF+eEoz48wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+U
+ykSTXYUbtsfTNRFQGBW2/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0CgIVAN4wtL5W
+Lv62jKcdskxNyz2NQoBx
+-----END DSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub
new file mode 100644
index 0000000000..4dbb1305b0
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_dsa_key.pub
@@ -0,0 +1,11 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1kc3MAAACBAIKVofMTa6XSApJTFqHlbRbxSIkvLiFeeAoSqlpSr1JJ1V1j
+YsrBV8ofWC3mK5p/UV/M6GwgL0b8YueNi21dlz3Zy/8Z97eBH6zSeLb74xf5P76YT9B2
+KW1e/8enbs/JtLrtKaIVbsj5FadPY4qUw+3DahS4p7O0J7lRaNqP/LkVAAAAFQDywJfU
+aYlN9GfOzUQB2NzU0WqrawAAAIA0xHHDxR9201VHQKtCPcCA9pc4YTh34bganheyS+cI
+fJxJUCO1jF5tSTNTO3lDp/8hpu4tR2B7eBetzwF62+twpun5dmAzT9WPYIViabLeKfqT
+MZmrsXDWxlqS7oA5Ty8trnCgFPa8BwcstPVssDOPu+IvTjxPox+Os495/yce8AAAAIBh
+DWFQJ1mf99sg92LalVq1dHLmVXb3PTJDfCO/Gz5NFmj9EZbAtdah/XcF3DeRF+eEoz48
+wQF/ExVxSMIhLdL+o+ElpVhlM7Yii+T7dPhkQfEul6zZXu+UykSTXYUbtsfTNRFQGBW2
+/GfnEc0mnIxfn9v10NEWMzlq5z9wT9P0Cg==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key
new file mode 100644
index 0000000000..79968bdd7d
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key
@@ -0,0 +1,16 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8semM4q843337
+zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RWRWzjaxSB
+6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4QIDAQAB
+AoGANmvJzJO5hkLuvyDZHKfAnGTtpifcR1wtSa9DjdKUyn8vhKF0mIimnbnYQEmW
+NUUb3gXCZLi9PvkpRSVRrASDOZwcjoU/Kvww163vBUVb2cOZfFhyn6o2Sk88Tt++
+udH3hdjpf9i7jTtUkUe+QYPsia+wgvvrmn4QrahLAH86+kECQQDx5gFeXTME3cnW
+WMpFz3PPumduzjqgqMMWEccX4FtQkMX/gyGa5UC7OHFyh0N/gSWvPbRHa8A6YgIt
+n8DO+fh5AkEAzbqX4DOn8NY6xJIi42q7l/2jIA0RkB6P7YugW5NblhqBZ0XDnpA5
+sMt+rz+K07u9XZtxgh1xi7mNfwY6lEAMqQJBAJBEauCKmRj35Z6OyeQku59SPsnY
++SJEREVvSNw2lH9SOKQQ4wPsYlTGbvKtNVZgAcen91L5MmYfeckYE/fdIZECQQCt
+64zxsTnM1I8iFxj/gP/OYlJBikrKt8udWmjaghzvLMEw+T2DExJyb9ZNeT53+UMB
+m6O+B/4xzU/djvp+0hbhAkAemIt+rA5kTmYlFndhpvzkSSM8a2EXsO4XIPgGWCTT
+tQKS/tTly0ADMjN/TVy11+9d6zcqadNVuHXHGtR4W0GR
+-----END RSA PRIVATE KEY-----
+
diff --git a/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub
new file mode 100644
index 0000000000..75d2025c71
--- /dev/null
+++ b/lib/ssh/test/ssh_upgrade_SUITE_data/ssh_host_rsa_key.pub
@@ -0,0 +1,5 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCZX+4FBDwZIh9y/Uxee1VJnEXlowpz2yDKwj8
+semM4q843337zbNfxHmladB1lpz2NqyxI175xMIJuDxogyZdsOxGnFAzAnthR4dqL/RW
+RWzjaxSB6IAO9SPYVVlrpZ+1hsjLW79fwXK/yc8VdhRuWTeQiRgYY2ek8+OKbOqz4Q==
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 9d486f8890..55d12abffe 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 3.2.4
+SSH_VSN = 4.2.1
+
APP_VSN = "ssh-$(SSH_VSN)"