diff options
Diffstat (limited to 'lib/ssh/doc/src')
-rw-r--r-- | lib/ssh/doc/src/Makefile | 40 | ||||
-rw-r--r-- | lib/ssh/doc/src/book.xml | 21 | ||||
-rw-r--r-- | lib/ssh/doc/src/configure_algos.xml | 428 | ||||
-rw-r--r-- | lib/ssh/doc/src/fascicules.xml | 18 | ||||
-rw-r--r-- | lib/ssh/doc/src/introduction.xml | 201 | ||||
-rw-r--r-- | lib/ssh/doc/src/notes.xml | 1639 | ||||
-rw-r--r-- | lib/ssh/doc/src/part_notes.xml | 37 | ||||
-rw-r--r-- | lib/ssh/doc/src/ref_man.xml | 25 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh.xml | 902 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_app.xml | 378 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_channel.xml | 317 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_client_key_api.xml | 132 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_connection.xml | 527 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_protocol.xml | 4 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_server_key_api.xml | 108 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftp.xml | 796 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftpd.xml | 77 | ||||
-rw-r--r-- | lib/ssh/doc/src/usersguide.xml | 29 | ||||
-rw-r--r-- | lib/ssh/doc/src/using_ssh.xml | 231 |
19 files changed, 4537 insertions, 1373 deletions
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile index 0e79d9979f..f54f5e0708 100644 --- a/lib/ssh/doc/src/Makefile +++ b/lib/ssh/doc/src/Makefile @@ -1,18 +1,19 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2012. All Rights Reserved. +# Copyright Ericsson AB 2004-2017. 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% # @@ -47,17 +48,18 @@ XML_REF3_FILES = ssh.xml \ XML_REF6_FILES = ssh_app.xml -XML_PART_FILES = part_notes.xml \ +XML_PART_FILES = \ usersguide.xml XML_CHAPTER_FILES = notes.xml \ introduction.xml \ - ssh_protocol.xml \ - using_ssh.xml + using_ssh.xml \ + configure_algos.xml +# ssh_protocol.xml \ BOOK_FILES = book.xml XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES)\ - $(XML_PART_FILES) $(XML_CHAPTER_FILES) + $(XML_PART_FILES) $(XML_CHAPTER_FILES) IMAGE_FILES = SSH_protocols.png @@ -83,10 +85,10 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf # ---------------------------------------------------- -# FLAGS +# FLAGS # ---------------------------------------------------- -XML_FLAGS += -DVIPS_FLAGS += +XML_FLAGS += +DVIPS_FLAGS += # ---------------------------------------------------- # Targets @@ -114,12 +116,12 @@ clean clean_docs: man: $(MAN3_FILES) $(MAN6_FILES) -debug opt: +debug opt: # ---------------------------------------------------- # Release Target -# ---------------------------------------------------- +# ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs diff --git a/lib/ssh/doc/src/book.xml b/lib/ssh/doc/src/book.xml index c031d872d7..bc104b274d 100644 --- a/lib/ssh/doc/src/book.xml +++ b/lib/ssh/doc/src/book.xml @@ -4,20 +4,21 @@ <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>2005</year><year>2013</year> + <year>2005</year><year>2016</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> diff --git a/lib/ssh/doc/src/configure_algos.xml b/lib/ssh/doc/src/configure_algos.xml new file mode 100644 index 0000000000..dd60324851 --- /dev/null +++ b/lib/ssh/doc/src/configure_algos.xml @@ -0,0 +1,428 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2017</year> + <year>2017</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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>Configuring algorithms in SSH</title> + <prepared></prepared> + <docno></docno> + <approved></approved> + <date></date> + <rev></rev> + <file>configure_algos.xml</file> + </header> + + <section> + <marker id="introduction"/> + <title>Introduction</title> + <p>To fully understand how to configure the algorithms, it is essential to have a basic understanding of the SSH protocol + and how OTP SSH app handles the corresponding items</p> + + <p>The first subsection will give a short background of the SSH protocol while later sections describes + the implementation and provides some examples</p> + + <section> + <title>Basics of the ssh protocol's algorithms handling</title> + + <p>SSH uses different sets of algorithms in different phases of a session. Which + algorithms to use is negotiated by the client and the server at the beginning of a session. + See <url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, + "The Secure Shell (SSH) Transport Layer Protocol" for details. + </p> + + <p>The negotiation is simple: both peers sends their list of supported alghorithms to the other part. + The first algorithm on the client's list that also in on the server's list is selected. So it is the + client's orderering of the list that gives the priority for the algorithms.</p> + + <p>There are five lists exchanged in the connection setup. Three of them are also divided in two + directions, to and from the server.</p> + + <p>The lists are (named as in the SSH application's options):</p> + <taglist> + <tag><c>kex</c></tag> + <item> + <p>Key exchange.</p> + <p>An algorithm is selected for computing a secret encryption key. Among examples are: + the old nowadays week <c>'diffie-hellman-group-exchange-sha1'</c> and the very strong and modern + <c>'ecdh-sha2-nistp512'</c>.</p> + </item> + + <tag><c>public_key</c></tag> + <item> + <p>Server host key</p> + <p>The asymetric encryption algorithm used in the server's private-public host key pair. + Examples include the well-known RSA <c>'ssh-rsa'</c> and elliptic curve <c>'ecdsa-sha2-nistp521'</c>. + </p> + </item> + + <tag><c>cipher</c></tag> + <item> + <p>Symetric cipher algorithm used for the payload encryption. This algorithm will use the key calculated + in the kex phase (together with other info) to genereate the actual key used. Examples are + tripple-DES <c>'3des-cbc'</c> and one of many AES variants <c>'aes192-ctr'</c>. + </p> + <p>This list is actually two - one for each direction server-to-client and client-to-server. Therefore it + is possible but rare to have different algorithms in the two directions in one connection.</p> + </item> + + <tag><c>mac</c></tag> + <item> + <p>Message authentication code</p> + <p>"Check sum" of each message sent between the peers. Examples are SHA <c>'hmac-sha1'</c> and + SHA2 <c>'hmac-sha2-512'</c>.</p> + <p>This list is also divided into two for the both directions</p> + </item> + + <tag><c>compression</c></tag> + <item> + <p>If and how to compress the message. Examples are <c>none</c>, that is, no compression and + <c>zlib</c>.</p> + <p>This list is also divided into two for the both directions</p> + </item> + + </taglist> + </section> + + <section> + <title>The SSH app's mechanism</title> + <p>The set of algorithms that the SSH app uses by default depends on the algoritms supported by the:</p> + <list> + <item><p><seealso marker="crypto:crypto">crypto</seealso> app,</p> + </item> + <item><p>The cryptolib OTP is linked with, usally the one the OS uses, probably OpenSSL,</p> + </item> + <item><p>and finaly what the SSH app implements</p> + </item> + </list> + <p>Due to this, it impossible to list in documentation what algorithms that are available in a certain installation.</p> + <p>There is an important command to list the actual algorithms and their ordering: + <seealso marker="ssh#default_algorithms-0">ssh:default_algorithms/0</seealso>.</p> + <code type="erl"> +0> ssh:default_algorithms(). +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521', + 'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256', + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['[email protected]', + 'aes256-ctr','aes192-ctr','[email protected]', + 'aes128-ctr','aes128-cbc','3des-cbc']}, + {server2client,['[email protected]','aes256-ctr', + 'aes192-ctr','[email protected]','aes128-ctr', + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'[email protected]',zlib]}, + {server2client,[none,'[email protected]',zlib]}]}] + + </code> + <p>To change the algorithm list, there are two options which can be used in + <seealso marker="ssh#connect-3">ssh:connect/2,3,4</seealso> + and + <seealso marker="ssh#daemon-2">ssh:daemon/2,3</seealso>. The options could of course + be used in all other functions that initiates connections.</p> + + <p>The options are <c>preferred_algorithms</c> and <c>modify_algorithms</c>. The first one + replaces the default set, while the latter modifies the default set.</p> + </section> + </section> + + <section> + <title>Replacing the default set: preferred_algorithms</title> + <p>See the <seealso marker="ssh#option_preferred_algorithms">Reference Manual</seealso> for details</p> + + <p>Here follows a series of examples ranging from simple to more complex.</p> + + <p>To forsee the effect of an option there is an experimental function <c>ssh:chk_algos_opts(Opts)</c>. + It mangles the options <c>preferred_algorithms</c> + and <c>modify_algorithms</c> in the same way as <c>ssh:dameon</c>, <c>ssh:connect</c> and their friends does.</p> + + <section> + <title>Example 1</title> + <p>Replace the kex algorithms list with the single algorithm <c>'diffie-hellman-group14-sha256'</c>:</p> + <code> +1> ssh:chk_algos_opts( + [{preferred_algorithms, + [{kex, ['diffie-hellman-group14-sha256']} + ] + } + ]). +[{kex,['diffie-hellman-group14-sha256']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256', + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['[email protected]', + 'aes256-ctr','aes192-ctr','[email protected]', + 'aes128-ctr','aes128-cbc','3des-cbc']}, + {server2client,['[email protected]','aes256-ctr', + 'aes192-ctr','[email protected]','aes128-ctr', + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'[email protected]',zlib]}, + {server2client,[none,'[email protected]',zlib]}]}] + </code> + <p>Note that the unmentioned lists (<c>public_key</c>, <c>cipher</c>, <c>mac</c> and <c>compression</c>) + are un-changed.</p> + </section> + + <section> + <title>Example 2</title> + <p>In the lists that are divided in two for the two directions (c.f <c>cipher</c>) it is possible + to change both directions at once:</p> + <code> +2> ssh:chk_algos_opts( + [{preferred_algorithms, + [{cipher,['aes128-ctr']} + ] + } + ]). +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521', + 'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256', + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['aes128-ctr']}, + {server2client,['aes128-ctr']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'[email protected]',zlib]}, + {server2client,[none,'[email protected]',zlib]}]}] + </code> + <p>Note that both lists in <c>cipher</c> has been changed to the provided value (<c>'aes128-ctr'</c>).</p> + </section> + + <section> + <title>Example 3</title> + <p>In the lists that are divided in two for the two directions (c.f <c>cipher</c>) it is possible + to change only one of the directions:</p> + <code> +3> ssh:chk_algos_opts( + [{preferred_algorithms, + [{cipher,[{client2server,['aes128-ctr']}]} + ] + } + ]). +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521', + 'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256', + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['aes128-ctr']}, + {server2client,['[email protected]','aes256-ctr', + 'aes192-ctr','[email protected]','aes128-ctr', + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'[email protected]',zlib]}, + {server2client,[none,'[email protected]',zlib]}]}] + </code> + </section> + + <section> + <title>Example 4</title> + <p>It is of course possible to change more than one list:</p> + <code> +4> ssh:chk_algos_opts( + [{preferred_algorithms, + [{cipher,['aes128-ctr']}, + {mac,['hmac-sha2-256']}, + {kex,['ecdh-sha2-nistp384']}, + {public_key,['ssh-rsa']}, + {compression,[{server2client,[none]}, + {client2server,[zlib]}]} + ] + } + ]). +[{kex,['ecdh-sha2-nistp384']}, + {public_key,['ssh-rsa']}, + {cipher,[{client2server,['aes128-ctr']}, + {server2client,['aes128-ctr']}]}, + {mac,[{client2server,['hmac-sha2-256']}, + {server2client,['hmac-sha2-256']}]}, + {compression,[{client2server,[zlib]}, + {server2client,[none]}]}] + + </code> + <p>Note that the ordering of the tuples in the lists didn't matter.</p> + </section> + </section> + + <section> + <title>Modifying the default set: modify_algorithms</title> + <p>A situation where it might be useful to add an algorithm is when one need to use a supported but disabled one. + An example is the <c>'diffie-hellman-group1-sha1'</c> which nowadays is very unsecure and therefore disabled. It is + however still supported and might be used.</p> + + <p>The option <c>preferred_algorithms</c> may be complicated to use for adding or removing single algorithms. + First one has to list them with <c>ssh:default_algorithms()</c> and then do changes in the lists.</p> + + <p>To facilitate addition or removal of algorithms the option <c>modify_algorithms</c> is available. + See the <seealso marker="ssh#option_modify_algorithms">Reference Manual</seealso> for details.</p> + + <p>The option takes a list with instructions to append, prepend or remove algorithms:</p> + <code type="erl"> +{modify_algorithms, [{append, ...}, + {prepend, ...}, + {rm, ...} + ]} + </code> + <p>Each of the <c>...</c> can be a <c>algs_list()</c> as the argument to the <c>preferred_algorithms</c> option.</p> + <section> + <title>Example 5</title> + <p>As an example let's add the Diffie-Hellman Group1 first in the kex list. It is supported according to + <seealso marker="SSH_app#supported_algos">Supported algoritms</seealso>.</p> + <code type="erl"> +5> ssh:chk_algos_opts( + [{modify_algorithms, + [{prepend, + [{kex,['diffie-hellman-group1-sha1']}] + } + ] + } + ]). +[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384', + 'ecdh-sha2-nistp521','ecdh-sha2-nistp256', + 'diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256', + 'rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['[email protected]', + 'aes256-ctr','aes192-ctr','[email protected]', + 'aes128-ctr','aes128-cbc','3des-cbc']}, + {server2client,['[email protected]','aes256-ctr', + 'aes192-ctr','[email protected]','aes128-ctr', + 'aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'[email protected]',zlib]}, + {server2client,[none,'[email protected]',zlib]}]}] + + </code> + <p>And the result shows that the Diffie-Hellman Group1 is added at the head of the kex list</p> + </section> + + <section> + <title>Example 6</title> + <p>In this example, we in put the 'diffie-hellman-group1-sha1' first and also move the + <c>'ecdh-sha2-nistp521'</c> to the end in the kex list, that is, <c>append</c> it.</p> + <code type="erl"> +6> ssh:chk_algos_opts( + [{modify_algorithms, + [{prepend, + [{kex, ['diffie-hellman-group1-sha1']} + ]}, + {append, + [{kex, ['ecdh-sha2-nistp521']} + ]} + ] + } + ]). +[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384', + 'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1','ecdh-sha2-nistp521']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + ..... +] + </code> + <p>Note that the appended algorithm is removed from its original place and then appended to the same list.</p> + </section> + + <section> + <title>Example 7</title> + <p>In this example, we use both options (<c>preferred_algorithms</c> and <c>modify_algorithms</c>) and + also try to prepend an unsupported algorithm. Any unsupported algorithm is quietly removed.</p> + <code type="erl"> +7> ssh:chk_algos_opts( + [{preferred_algorithms, + [{cipher,['aes128-ctr']}, + {mac,['hmac-sha2-256']}, + {kex,['ecdh-sha2-nistp384']}, + {public_key,['ssh-rsa']}, + {compression,[{server2client,[none]}, + {client2server,[zlib]}]} + ] + }, + {modify_algorithms, + [{prepend, + [{kex, ['some unsupported algorithm']} + ]}, + {append, + [{kex, ['diffie-hellman-group1-sha1']} + ]} + ] + } + ]). +[{kex,['ecdh-sha2-nistp384','diffie-hellman-group1-sha1']}, + {public_key,['ssh-rsa']}, + {cipher,[{client2server,['aes128-ctr']}, + {server2client,['aes128-ctr']}]}, + {mac,[{client2server,['hmac-sha2-256']}, + {server2client,['hmac-sha2-256']}]}, + {compression,[{client2server,[zlib]}, + {server2client,[none]}]}] + + </code> + <p>It is of course questionable why anyone would like to use the both these options together, + but it is possible if an unforeseen need should arise.</p> + </section> + + + + </section> + +</chapter> diff --git a/lib/ssh/doc/src/fascicules.xml b/lib/ssh/doc/src/fascicules.xml deleted file mode 100644 index 7e99398c16..0000000000 --- a/lib/ssh/doc/src/fascicules.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE fascicules SYSTEM "fascicules.dtd"> - -<fascicules> - <fascicule file="usersguide" href="usersguide_frame.html" entry="no"> - User's Guide - </fascicule> - <fascicule file="ref_man" href="ref_man_frame.html" entry="yes"> - Reference Manual - </fascicule> - <fascicule file="part_notes" href="part_notes_frame.html" entry="no"> - Release Notes - </fascicule> - <fascicule file="" href="../../../../doc/print.html" entry="no"> - Off-Print - </fascicule> -</fascicules> - diff --git a/lib/ssh/doc/src/introduction.xml b/lib/ssh/doc/src/introduction.xml index b42910cb34..b7a73e2597 100644 --- a/lib/ssh/doc/src/introduction.xml +++ b/lib/ssh/doc/src/introduction.xml @@ -5,51 +5,200 @@ <header> <copyright> <year>2012</year> - <year>2013</year> + <year>2016</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>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/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..1f01ce5e6c 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>2017</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,1618 @@ <file>notes.xml</file> </header> +<section><title>Ssh 4.6.9.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Incompatibility with newer OpenSSH fixed. Previously + versions 7.8 and later could cause Erlang SSH to exit.</p> + <p> + Own Id: OTP-15413</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.9.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + SFTP clients reported the error reason <c>""</c> if a + non-OTP sftp server was killed during a long file + transmission.</p> + <p> + Now the signal name (for example <c>"KILL"</c>) will be + the error reason if the server's reason is empty.</p> + <p> + The documentation also lacked type information about this + class of errors.</p> + <p> + Own Id: OTP-15148 Aux Id: ERIERL-194 </p> + </item> + <item> + <p> + Fix ssh_sftp decode error for sftp protocol version 4</p> + <p> + Own Id: OTP-15149 Aux Id: ERIERL-199 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Host key hash erroneously calculated for clients + following draft-00 of RFC 4419, for example PuTTY</p> + <p> + Own Id: OTP-15064</p> + </item> + <item> + <p> + Renegotiation could fail in some states</p> + <p> + Own Id: OTP-15066</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + An ssh_sftp server (running version 6) could fail if it + is told to remove a file which in fact is a directory.</p> + <p> + Own Id: OTP-15004</p> + </item> + <item> + <p> + Fix rare spurios shutdowns of ssh servers when receiveing + <c>{'EXIT',_,normal}</c> messages.</p> + <p> + Own Id: OTP-15018</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bad spec in ssh.hrl: <c>double_algs()</c>.</p> + <p> + Own Id: OTP-14990</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Remove a blocking risk when a channel is closed and an + operation is tried on that channel after at least a + second's time gap.</p> + <p> + Own Id: OTP-14939</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added ssh_compat_SUITE.</p> + <p> + This suite contains a number of interoperability tests + mainly with OpenSSH. The tests start docker containers + with different OpenSSH and OpenSSL/LibreSSLcryptolib + versions and performs a number of tests of supported + algorithms.</p> + <p> + All login methods and all user's public key types are + tested both for the client and the server.</p> + <p> + All algorithms for kex, cipher, host key, mac and + compressions are tested with a number of exec and sftp + tests, both for the client and the server.</p> + <p> + Own Id: OTP-14194 Aux Id: OTP-12487 </p> + </item> + <item> + <p> + Default exec is disabled when a user-defined shell is + enabled.</p> + <p> + Own Id: OTP-14881</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Adjusted supervisor timeouts</p> + <p> + Own Id: OTP-14907</p> + </item> + <item> + <p> + Remove ERROR messages for slow process exits</p> + <p> + Own Id: OTP-14930</p> + </item> + </list> + </section> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add option <c>save_accepted_host</c> to + <c>ssh:connection</c>. This option, if set to false, + inhibits saving host keys to e.g the file + <c>known_hosts</c>.</p> + <p> + Own Id: OTP-14935</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix problem with OpenSSH 7.2 (and later) clients that has + used sha1 instead of sha2 for rsa-sha-256/512 user's + public keys.</p> + <p> + Own Id: OTP-14827 Aux Id: ERL-531 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Passphrase option for ecdsa public keys was missing.</p> + <p> + Own Id: OTP-14602</p> + </item> + </list> + </section> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The host and user public key handling is hardened so that + a faulty plugin can't deliver a key of wrong type.</p> + <p> + Better checks in the server of the available hostkey's + types at start and at each accept.</p> + <p> + Better checks in the client of the available user public + key types at connect.</p> + <p> + Own Id: OTP-14676 Aux Id: ERIERL-52, OTP-14570 </p> + </item> + <item> + <p> + SSH can now fetch the host key from the private keys + stored in an Engine. See the crypto application for + details about Engines.</p> + <p> + Own Id: OTP-14757</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.2</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Trailing white space was removed at end of the + hello-string. This caused interoperability problems with + some other ssh-implementations (e.g OpenSSH 7.3p1 on + Solaris 11)</p> + <p> + Own Id: OTP-14763 Aux Id: ERIERL-74 </p> + </item> + <item> + <p> + Fixes that tcp connections that was immediately closed + (SYN, SYNACK, ACK, RST) by a client could be left in a + zombie state.</p> + <p> + Own Id: OTP-14778 Aux Id: ERIERL-104 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6.1</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed broken printout</p> + <p> + Own Id: OTP-14645</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Disable aes_gcm ciphers if peer is OpenSSH 6.2 which is + known to have trouble with them in some cases.</p> + <p> + Own Id: OTP-14638</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Enables the <c>ssh_io module</c> to also accept binary + values when reading standard_io instead of getting stuck + in the receive clause.</p> + <p> + Own Id: OTP-14506 Aux Id: PR1503 </p> + </item> + <item> + <p> + Previously, the file owner access permission in response + to ssh_sftp:read_file_info/2 function was always + <c>read_write</c>. With this fix, the actual value of + file owner access permission is added to the returning + record. That value is calculated from file mode value.</p> + <p> + Own Id: OTP-14550 Aux Id: PR1533 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new option <c>modify_algorithms</c> is implemented. It + enables specifying changes on the default algorithms + list. See the reference manual and the SSH User's Guide + chapter "Configuring algorithms in SSH".</p> + <p> + Own Id: OTP-14568</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + All unknown options are sent to the transport handler + regardless of type.</p> + <p> + Own Id: OTP-14541 Aux Id: EIRERL-63 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The internal handling of SSH options is re-written.</p> + <p> + Previously there were no checks if a client option was + given to a daemon or vice versa. This is corrected now. + If your code has e.g. a client-only option in a call to + start a daemon, the call will fail.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-12872</p> + </item> + <item> + <p> + Modernization of key exchange algorithms. See + draft-ietf-curdle-ssh-kex-sha2 for a discussion.</p> + <p> + Removed an outdated weak algorithm and added stronger + replacements to keep interoperability with other modern + ssh clients and servers. The default ordering of the + algorithms is also adjusted.</p> + <p> + Retired: The nowadays unsecure key-exchange + <c>diffie-hellman-group1-sha1</c> is not enabled by + default, but can be enabled with the option + <c>preferred-algorithms</c>.</p> + <p> + Added: The new stronger key-exchange + <c>diffie-hellman-group16-sha512</c>, + <c>diffie-hellman-group18-sha512</c> and + <c>diffie-hellman-group14-sha256</c> are added and + enabled by default.</p> + <p> + The questionable [RFC 6194] sha1-based algorithms + <c>diffie-hellman-group-exchange-sha1</c> and + <c>diffie-hellman-group14-sha1</c> are however still kept + enabled by default for compatibility with ancient clients + and servers that lack modern key-exchange alternatives. + When the draft-ietf-curdle-ssh-kex-sha2 becomes an rfc, + those sha1-based algorithms and + <c>diffie-hellman-group1-sha1</c> will be deprecated by + IETF. They might then be removed from the default list in + Erlang/OTP.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14110</p> + </item> + <item> + <p> + Modernized internal representation of sftp by use of + maps.</p> + <p> + Own Id: OTP-14117</p> + </item> + <item> + <p> + The Extension Negotiation Mechanism and the extension + <c>server-sig-algs</c> in + draft-ietf-curdle-ssh-ext-info-05 are implemented.</p> + <p> + The related draft-ietf-curdle-rsa-sha2-05 is implemented + and introduces the signature algorithms + <c>rsa-sha2-256</c> and <c>rsa-sha2-512</c>.</p> + <p> + Own Id: OTP-14193</p> + </item> + <item> + <p> + The 'timeout' and 'connect_timeout' handling in + ssh_sftp:start_channel documentation is clarified.</p> + <p> + Own Id: OTP-14216</p> + </item> + <item> + <p> + The functions <c>ssh:connect</c>, <c>ssh:shell</c> and + <c>ssh:start_channel</c> now accept an IP-tuple as Host + destination argument.</p> + <p> + Own Id: OTP-14243</p> + </item> + <item> + <p> + The function <c>ssh:daemon_info/1</c> now returns Host + and Profile as well as the Port info in the property + list.</p> + <p> + Own Id: OTP-14259</p> + </item> + <item> + <p> + Removed the option <c>public_key_alg</c> which was + deprecated in 18.2. Use <c>pref_public_key_algs</c> + instead.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14263</p> + </item> + <item> + <p> + The SSH application is refactored regarding daemon + starting. The resolution of contradicting <c>Host</c> + argument and <c>ip</c> option were not described. There + were also strange corner cases when the <c>'any'</c> + value was used in <c>Host</c> argument or <c>ip</c> + option. This is (hopefully) resolved now, but it may + cause incompatibilities for code using both <c>Host</c> + and the <c>ip</c> option. The value 'loopback' has been + added for a correct way of naming those addresses.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14264</p> + </item> + <item> + <p> + The supervisor code is refactored. The naming of + listening IP-Port-Profile triples are slightly changed to + improve consistency in strange corner cases as resolved + by OTP-14264</p> + <p> + Own Id: OTP-14267 Aux Id: OTP-14266 </p> + </item> + <item> + <p> + The <c>idle_time</c> option can now be used in daemons.</p> + <p> + Own Id: OTP-14312</p> + </item> + <item> + <p> + Added test cases for IETF-CURDLE Extension Negotiation + (ext-info)</p> + <p> + Own Id: OTP-14361</p> + </item> + <item> + <p> + Testcases for IETF-CURDLE extension + <c>server-sig-algs</c> including <c>rsa-sha2-*</c></p> + <p> + Own Id: OTP-14362 Aux Id: OTP-14361 </p> + </item> + <item> + <p> + The option <c>auth_methods</c> can now also be used in + clients to select which authentication options that are + used and in which order.</p> + <p> + Own Id: OTP-14399</p> + </item> + <item> + <p> + Checks that a ECDSA public key (<c>ecdsa-sha2-nistp*</c>) + stored in a file has the correct size.</p> + <p> + Own Id: OTP-14410</p> + </item> + </list> + </section> + +</section> + + +<section><title>Ssh 4.4.2.2</title> + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Default exec is disabled when a user-defined shell is + enabled.</p> + <p> + Own Id: OTP-14881</p> + </item> + </list> + </section> +</section> + + +<section><title>Ssh 4.4.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Trailing white space was removed at end of the + hello-string. This caused interoperability problems with + some other ssh-implementations (e.g OpenSSH 7.3p1 on + Solaris 11)</p> + <p> + Own Id: OTP-14763 Aux Id: ERIERL-74 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.4.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + ssh:daemon_info/1 crashed if the listening IP was not + 'any'</p> + <p> + Own Id: OTP-14298 Aux Id: seq13294 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.4.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bug when opening connections. If the tcp setup + failed, that would in some cases not result in an error + return value.</p> + <p> + Own Id: OTP-14108</p> + </item> + <item> + <p> + Reduce information leakage in case of decryption errors.</p> + <p> + Own Id: OTP-14109</p> + </item> + <item> + <p> + The key exchange algorithm + diffie-hellman-group-exchange-sha* has a server-option + <c>{dh_gex_limits,{Min,Max}}</c>. There was a hostkey + signature validation error on the client side if the + option was used and the <c>Min</c> or the <c>Max</c> + differed from the corresponding values obtained from the + client.</p> + <p> + This bug is now corrected.</p> + <p> + Own Id: OTP-14166</p> + </item> + <item> + <p> + The sftpd server now correctly uses <c>root_dir</c> and + <c>cwd</c> when resolving file paths if both are + provided. The <c>cwd</c> handling is also corrected.</p> + <p> + Thanks to kape1395!</p> + <p> + Own Id: OTP-14225 Aux Id: PR-1331, PR-1335 </p> + </item> + <item> + <p> + Ssh_cli used a function that does not handle non-utf8 + unicode correctly.</p> + <p> + Own Id: OTP-14230 Aux Id: ERL-364 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The implementation of the key exchange algorithms + diffie-hellman-group-exchange-sha* are optimized, up to a + factor of 11 for the slowest ( = biggest and safest) + group size.</p> + <p> + Own Id: OTP-14169 Aux Id: seq-13261 </p> + </item> + <item> + <p> + The ssh host key fingerprint generation now also takes a + list of algorithms and returns a list of corresponding + fingerprints. See + <c>public_key:ssh_hostkey_fingerprint/2</c> and the + option <c>silently_accept_hosts</c> in + <c>ssh:connect</c>.</p> + <p> + Own Id: OTP-14223</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A file read with an sftp client could loose data if the + packet_size is set to larger than 64k. This is corrected + now in such a way that the packet_size is silently + lowered if there is a risk for data loss.</p> + <p> + Own Id: OTP-13857 Aux Id: ERL-238, OTP-13858 </p> + </item> + <item> + <p> + When user defined SSH shell REPL process exits with + reason normal, the SSH channel callback module should + report successful exit status to the SSH client. This + provides simple way for SSH clients to check for + successful completion of executed commands. (Thanks to + isvilen)</p> + <p> + Own Id: OTP-13905 Aux Id: PR-1173 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Extended the option <c>silently_accept_hosts</c> for + <c>ssh:connect</c> to make it possible for the client to + check the SSH host key fingerprint string. Se the + reference manual for SSH.</p> + <p> + Own Id: OTP-13887 Aux Id: OTP-13888 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Re-negotiation problems with OpenSSH client solved.</p> + <p> + Own Id: OTP-13972</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If a client illegaly sends an info-line and then + immediatly closes the TCP-connection, a badmatch + exception was raised.</p> + <p> + Own Id: OTP-13966</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Intermittent ssh ERROR REPORT mentioning + nonblocking_sender</p> + <p> + Own Id: OTP-13953 Aux Id: seq13199 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Handle all possible exit values that should be + interpreted as {error, closed}. Failing to do so could + lead to unexpected crashes for users of the ssh + application.</p> + <p> + Own Id: OTP-13932 Aux Id: seq13189 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Upgrade of an established client connection could crash + because the ssh client supervisors children had wrong + type. This is fixed now.</p> + <p> + Own Id: OTP-13782 Aux Id: seq13158 </p> + </item> + <item> + <p> + Partly checks the public key early in public key + authorization</p> + <p> + Own Id: OTP-13847 Aux Id: + defensics-ssh3.1.0-190243,205277,219318 </p> + </item> + <item> + <p> + Corrected handling of SHA for ECDSA (Elliptic curve + public keys)</p> + <p> + Own Id: OTP-13850 Aux Id: defensics-ssh3.1.0-214168 </p> + </item> + <item> + <p> + Problems found by test suites as well as by + Codenomicon/Defensics fixed: - reduce max random padding + to 15 bytes (Codenomicon/Defensics) - inclomplete pdu + handling (Codenomicon/Defensics) - badmatch in test suite + - non-blocking send fixes deadlock in + ssh_connection_SUITE:interrupted_send</p> + <p> + Own Id: OTP-13854</p> + </item> + <item> + <p> + Caller is now notified when a tcp close is received.</p> + <p> + Own Id: OTP-13859 Aux Id: seq13177 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Use application:ensure_all_started/2 instead of + hard-coding deps</p> + <p> + Own Id: OTP-13843 Aux Id: PR-1147 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + SSH client does not any longer retry a bad password given + as option to ssh:connect et al.</p> + <p> + Own Id: OTP-13674 Aux Id: TR-HU92273 </p> + </item> + <item> + <p> + Removed possible hanging risk for a certain timing + sequence when communicating client and server executes on + the same node.</p> + <p> + Own Id: OTP-13715</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.3</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A socket created and connected by gen_tcp could now be + used as input to ssh:connect, ssh:shell, + ssh_sftp:start_channel and ssh:daemon.</p> + <p> + Own Id: OTP-12860</p> + </item> + <item> + <p> + Some time optimization mainly in message encoding.</p> + <p> + Own Id: OTP-13131</p> + </item> + <item> + <p> + Optimized the sftp client time by setting new packet and + window sizes.</p> + <p> + Own Id: OTP-13175</p> + </item> + <item> + <p> + The <c>ssh_connection_handler</c> module in SSH is + changed and now uses the new behaviour <c>gen_statem</c>. </p> + <p> + The module can be used as an example of a + <c>gen_statem</c> callback module but with a warning: + This commit of ssh is just a straightforward port from + gen_fsm to gen_statem with some code cleaning. Since the + state machine and the state callbacks are almost + unchanged the ssh module does not demonstrate the full + potential of the new behaviour.</p> + <p> + The "new" state machine uses compound states. The ssh + server and client state machines are quite similar but + differences exist. With <c>gen_fsm</c> there were flags + in the user data which in fact implemented "substates". + Now with <c>gen_statem</c> those are made explicit in the + state names, eg. the state <c>userauth</c> and the binary + <c>role</c>-flag becomes the two state names + <c>{userauth, server}</c> and <c>{userauth, client}</c>.</p> + <p> + Own Id: OTP-13267</p> + </item> + <item> + <p> + The <c>{error, Reason}</c> tuples returned from + <c>ssh_sftp</c> api functions are described.</p> + <p> + Own Id: OTP-13347 Aux Id: ERL-86 </p> + </item> + <item> + <p> + Added -spec in ssh</p> + <p> + Own Id: OTP-13479</p> + </item> + <item> + <p> + It is now possible to call <c>ssh:daemon/{1,2,3}</c> with + <c>Port=0</c>. This makes the daemon select a free + listening tcp port before opening it. To find this port + number after the call, use the new function + <c>ssh:daemon_info/1</c>. See the reference manual for + details.</p> + <p> + Own Id: OTP-13527</p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.2.2.5</title> + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Default exec is disabled when a user-defined shell is + enabled.</p> + <p> + Own Id: OTP-14881</p> + </item> + </list> + </section> +</section> + + +<section><title>Ssh 4.2.2.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Trailing white space was removed at end of the + hello-string. This caused interoperability problems with + some other ssh-implementations (e.g OpenSSH 7.3p1 on + Solaris 11)</p> + <p> + Own Id: OTP-14763 Aux Id: ERIERL-74 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.2.2.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The key exchange algorithm + diffie-hellman-group-exchange-sha* has a server-option + <c>{dh_gex_limits,{Min,Max}}</c>. There was a hostkey + signature validation error on the client side if the + option was used and the <c>Min</c> or the <c>Max</c> + differed from the corresponding values obtained from the + client.</p> + <p> + This bug is now corrected.</p> + <p> + Own Id: OTP-14166</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Key exchange algorithms + diffie-hellman-group-exchange-sha* optimized, up to a + factor of 11 for the slowest ( = biggest and safest) one.</p> + <p> + Own Id: OTP-14169 Aux Id: seq-13261 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.2.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Upgrade of an established client connection could crash + because the ssh client supervisors children had wrong + type. This is fixed now.</p> + <p> + Own Id: OTP-13782 Aux Id: seq13158 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.2.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + SSH client does not any longer retry a bad password given + as option to ssh:connect et al.</p> + <p> + Own Id: OTP-13674 Aux Id: TR-HU92273 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.2.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Documentation correction of <c>ssh_sftp:position/4</c></p> + <p> + Thanks to Rabbe Fogelholm.</p> + <p> + Own Id: OTP-13305 Aux Id: ERL-87 </p> + </item> + </list> + </section> + +</section> + +<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 + [email protected].</p> + <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 +1654,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 deleted file mode 100644 index c5cc163717..0000000000 --- a/lib/ssh/doc/src/part_notes.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE part SYSTEM "part.dtd"> - -<part xmlns:xi="http://www.w3.org/2001/XInclude"> - <header> - <copyright> - <year>2004</year><year>2013</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. - - </legalnotice> - - <title>SSH Release Notes</title> - <prepared>Jakob Cederlund</prepared> - <docno></docno> - <date></date> - <rev>%VSN%</rev> - <file>part_notes.sgml</file> - </header> - <description> - <p>This document describes the changes made to the SSH application. - </p> - </description> - <xi:include file="notes.xml"/> -</part> - diff --git a/lib/ssh/doc/src/ref_man.xml b/lib/ssh/doc/src/ref_man.xml index 55339298e8..140ebd8c76 100644 --- a/lib/ssh/doc/src/ref_man.xml +++ b/lib/ssh/doc/src/ref_man.xml @@ -4,20 +4,21 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</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> @@ -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..acf94ff6af 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -4,72 +4,121 @@ <erlref> <header> <copyright> - <year>2004</year><year>2014</year> + <year>2004</year><year>2017</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> + + <tag><c>modify_algs_list() =</c></tag> + <item><p><c>list( {append,algs_list()} | {prepend,algs_list()} | {rm,algs_list()} )</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> @@ -79,106 +128,314 @@ <func> <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> + <name>connect(Host, Port, Options, Timeout) -> </name> + <name>connect(TcpSocket, Options) -> </name> + <name>connect(TcpSocket, Options, Timeout) -> + {ok, ssh_connection_ref()} | {error, Reason}</name> + <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> + <v>TcpSocket = port()</v> + <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</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> - <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>IP version to use.</p> + </item> + <tag><marker id="opt_user_dir"></marker><c><![CDATA[{user_dir, string()}]]></c></tag> + <item> + <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> + <tag><c><![CDATA[{ecdsa_pass_phrase, string()}]]></c></tag> <item> - <p>When true hosts are added to the - file <c><![CDATA[known_hosts]]></c> without asking the user. - Defaults to false. + <p>If the user ECDSA key is protected by a passphrase, it can be + supplied with this option. </p> </item> + <tag> + <c><![CDATA[{silently_accept_hosts, boolean()}]]></c> <br/> + <c><![CDATA[{silently_accept_hosts, CallbackFun}]]></c> <br/> + <c><![CDATA[{silently_accept_hosts, {HashAlgoSpec, CallbackFun} }]]></c> <br/> + <br/> + <c><![CDATA[HashAlgoSpec = crypto:digest_type() | [ crypto:digest_type() ] ]]></c><br/> + <c><![CDATA[CallbackFun = fun(PeerName, FingerPrint) -> boolean()]]></c><br/> + <c><![CDATA[PeerName = string()]]></c><br/> + <c><![CDATA[FingerPrint = string() | [ string() ] ]]></c> + </tag> + <item> + <p>This option guides the <c>connect</c> function how to act when the connected server presents a Host + Key that the client has not seen before. The default is to ask the user with a question on stdio of whether to + accept or reject the new Host Key. + See also the option <seealso marker="#opt_user_dir"><c>user_dir</c></seealso> + for the path to the file <c>known_hosts</c> where previously accepted Host Keys are recorded. + </p> + <p>The option can be given in three different forms as seen above:</p> + <list> + <item>The value is a <c>boolean()</c>. The value <c>true</c> will make the client accept any unknown + Host Key without any user interaction. The value <c>false</c> keeps the default behaviour of asking the + the user on stdio. + </item> + <item>A <c>CallbackFun</c> will be called and the boolean return value <c>true</c> will make the client + accept the Host Key. A return value of <c>false</c> will make the client to reject the Host Key and therefore + also the connection will be closed. The arguments to the fun are: + <list type="bulleted"> + <item><c>PeerName</c> - a string with the name or address of the remote host.</item> + <item><c>FingerPrint</c> - the fingerprint of the Host Key as + <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-1">public_key:ssh_hostkey_fingerprint/1</seealso> + calculates it. + </item> + </list> + </item> + <item>A tuple <c>{HashAlgoSpec, CallbackFun}</c>. The <c>HashAlgoSpec</c> specifies which hash algorithm + shall be used to calculate the fingerprint used in the call of the <c>CallbackFun</c>. The <c>HashALgoSpec</c> + is either an atom or a list of atoms as the first argument in + <seealso marker="public_key:public_key#ssh_hostkey_fingerprint-2">public_key:ssh_hostkey_fingerprint/2</seealso>. + If it is a list of hash algorithm names, the <c>FingerPrint</c> argument in the <c>CallbackFun</c> will be + a list of fingerprints in the same order as the corresponding name in the <c>HashAlgoSpec</c> list. + </item> + </list> + </item> + + <tag><c><![CDATA[{save_accepted_host, boolean()}]]></c></tag> + <item> + <p>If <c>true</c>, the client saves an accepted host key to avoid the + accept question the next time the same host is connected. If the option + <c>key_cb</c> is not present, the key is saved in the file "known_hosts". + </p> + <p>If <c>false</c>, the key is not saved and the key will still be unknown + at the next access of the same host. + </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 options are not always desirable + to use from a security point of view.</p> </item> - <tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag> + + <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>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> + <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[{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 the <c>public_key</c> entry in + <seealso marker="#default_algorithms/0">ssh:default_algorithms/0</seealso>. + </p> + <p>If there is no public key of a specified type available, the corresponding entry is ignored. + Note that the available set is dependent on the underlying cryptolib and current user's public keys. + </p> + </item> + + <tag><marker id="option_preferred_algorithms"></marker> + <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> + + <p>For background and more examples see the <seealso marker="configure_algos#introduction">User's Guide</seealso>.</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><marker id="option_modify_algorithms"></marker> + <c><![CDATA[{modify_algorithms, modify_algs_list()}]]></c></tag> + <item> + <p>Modifies the list of algorithms to use in the algorithm negotiation. The modifications are + applied after the option <c>preferred_algorithms</c> (if existing) is applied.</p> + <p>The algoritm for modifications works like this:</p> + <list> + <item> + <p>Input is the <c>modify_algs_list()</c> and a set of algorithms <c>A</c> + obtained from the <c>preferred_algorithms</c> option if existing, or else from the + <seealso marker="ssh#default_algorithms-0">ssh:default_algorithms/0</seealso>. + </p> + </item> + <item> + <p>The head of the <c>modify_algs_list()</c> modifies <c>A</c> giving the result <c>A'</c>.</p> + <p>The possible modifications are:</p> + <list> + <item> + <p>Append or prepend supported but not enabled algorithm(s) to the list of + algorithms. If the wanted algorithms already are in <c>A</c> they will first + be removed and then appended or prepended, + </p> + </item> + <item> + <p>Remove (rm) one or more algorithms from <c>A</c>. + </p> + </item> + </list> + </item> + <item> + <p>Repeat the modification step with the tail of <c>modify_algs_list()</c> and the resulting + <c>A'</c>. + </p> + </item> + </list> + <p>If an unsupported algorithm is in the <c>modify_algs_list()</c>, it will be silently ignored</p> + <p>If there are more than one modify_algorithms options, the result is undefined.</p> + <p>Here is an example of this option:</p> + <code> +{modify_algorithms, + [{prepend, [{kex, ['diffie-hellman-group1-sha1']}], + {rm, [{compression, [none]}]} + ] +} +</code> + <p>The example specifies that:</p> + <list> + <item><p>the old key exchange algorithm 'diffie-hellman-group1-sha1' should be + the main alternative. It will be the main alternative since it is prepened to the list</p> + </item> + <item><p>The compression algorithm none (= no compression) is removed so compression is enforced</p> + </item> + </list> + <p>For background and more examples see the <seealso marker="configure_algos#introduction">User's Guide</seealso>.</p> + </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[{auth_methods, string()}]]></c></tag> + <item> + <p>Comma-separated string that determines which + authentication methods that the client shall support and + in which order they are tried. Defaults to + <c><![CDATA["publickey,keyboard-interactive,password"]]></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[{send_ext_info, boolean()}]]></c></tag> + <item> + <p>Send a list of extensions to the server if the server has asked for it. See + <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details. + </p> + <p>Currently the client do not react on any extensions. + </p> + <p>Default value is <c>true</c>. + </p> + </item--> + + <tag><c><![CDATA[{recv_ext_info, boolean()}]]></c></tag> + <item> + <p>Tell the server that the client accepts extension negotiation. See + <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details. + </p> + <p>Currently implemented extension is <c>server-sig-algs</c> which is the list of the server's preferred + user's public key algorithms. + </p> + <p>Default value is <c>true</c>. + </p> + </item> + + <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 +448,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,143 +472,342 @@ <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> <func> <name>daemon(Port) -> </name> <name>daemon(Port, Options) -> </name> - <name>daemon(HostAddress, Port, Options) -> {ok, - ssh_daemon_ref()} | {error, atom()}</name> + <name>daemon(HostAddress, Port, Options) -> </name> + <name>daemon(TcpSocket) -> </name> + <name>daemon(TcpSocket, Options) -> {ok, ssh_daemon_ref()} | {error, atom()}</name> <fsummary>Starts a server listening for SSH connections on the given port.</fsummary> <type> <v>Port = integer()</v> - <v>HostAddress = ip_address() | any</v> + <v>HostAddress = ip_address() | any | loopback</v> <v>Options = [{Option, Value}]</v> <v>Option = atom()</v> <v>Value = term()</v> + <v>TcpSocket = port()</v> + <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</c></d> </type> <desc> <p>Starts a server listening for SSH connections on the given - port.</p> - <p>Options are:</p> + port. If the <c>Port</c> is 0, a random free port is selected. See + <seealso marker="#daemon_info/1">daemon_info/1</seealso> about how to find the selected port number.</p> + + <p>Please note that by historical reasons both the <c>HostAddress</c> argument and the inet socket option + <c>ip</c> set the listening address. This is a source of possible inconsistent settings.</p> + + <p>The rules for handling the two address passing options are:</p> + <list> + <item>if <c>HostAddress</c> is an IP-address, that IP-address is the listening address. + An 'ip'-option will be discarded if present.</item> + + <item>if <c>HostAddress</c> is <c>loopback</c>, the listening address + is <c>loopback</c> and an loopback address will be choosen by the underlying layers. + An 'ip'-option will be discarded if present.</item> + + <item>if <c>HostAddress</c> is <c>any</c> and no 'ip'-option is present, the listening address is + <c>any</c> and the socket will listen to all addresses</item> + + <item>if <c>HostAddress</c> is <c>any</c> and an 'ip'-option is present, the listening address is + set to the value of the 'ip'-option</item> + </list> + + <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> + <p>Note that the client is free to use any order and to exclude methods.</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>Provide a function for password validation. This is called - with user and password as strings, and should return + <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> + + <p>For background and more examples see the <seealso marker="configure_algos#introduction">User's Guide</seealso>.</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><marker id="option_modify_algorithms"></marker> + <c><![CDATA[{modify_algorithms, modify_algs_list()}]]></c></tag> + <item> + <p>Modifies the list of algorithms to use in the algorithm negotiation. The modifications are + applied after the option <c>preferred_algorithms</c> is applied (if existing)</p> + <p>The possible modifications are to:</p> + <list> + <item><p>Append or prepend supported but not enabled algorithm(s) to the list of + algorithms.</p><p>If the wanted algorithms already are in the list of algorithms, they will first + be removed and then appended or prepended. + </p> + </item> + <item><p>Remove (rm) one or more algorithms from the list of algorithms.</p></item> + </list> + <p>If an unsupported algorithm is in the list, it will be silently ignored</p> + + <p>Here is an example of this option:</p> + <code> +{modify_algorithms, + [{prepend, [{kex, ['diffie-hellman-group1-sha1']}], + {rm, [{compression, [none]}]} + ] +} +</code> + <p>The example specifies that:</p> + <list> + <item><p>the old key exchange algorithm 'diffie-hellman-group1-sha1' should be + the main alternative. It will be the main alternative since it is prepened to the list</p> + </item> + <item><p>The compression algorithm none (= no compression) is removed so compression is enforced</p> + </item> + </list> + <p>For background and more examples see the <seealso marker="configure_algos#introduction">User's Guide</seealso>.</p> + </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 < 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>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 +825,80 @@ </p> </item> - <tag><c><![CDATA[{key_cb, atom()}]]></c></tag> + <tag><c><![CDATA[{send_ext_info, boolean()}]]></c></tag> + <item> + <p>Send a list of extensions to the client if the client has asked for it. See + <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details. + </p> + <p>Currently implemented extension is sending <c>server-sig-algs</c> which is the list of the server's preferred + user's public key algorithms. + </p> + <p>Default value is <c>true</c>. + </p> + </item> + + <!--tag><c><![CDATA[{recv_ext_info, boolean()}]]></c></tag> + <item> + <p>Tell the client that the server accepts extension negotiation. See + <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url> for details. + </p> + <p>Default value is <c>true</c>. + </p> + </item--> + + <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. 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>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>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[{idle_time, integer()}]]></c></tag> + <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> @@ -403,21 +912,57 @@ </desc> </func> + <func> + <name>daemon_info(Daemon) -> {ok, [DaemonInfo]} | {error,Error}</name> + <fsummary>Get info about a daemon</fsummary> + <type> + <v>DaemonInfo = {port,Port::pos_integer()} | {listen_address, any|ip_address()} | {profile,atom()}</v> + <v>Port = integer()</v> + <v>Error = bad_daemon_ref</v> + </type> + <desc> + <p>Returns a key-value list with information about the daemon. For now, only the listening port is returned. This is intended for the case the daemon is started with the port set to 0.</p> + </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> + <name>shell(Host, Port, Option) -> </name> + <name>shell(TcpSocket) -> _</name> + <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> + <v>TcpSocket = port()</v> + <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</c></d> </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 +971,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 Kernel.</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 Kernel.</p> </desc> </func> @@ -471,7 +1017,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 +1025,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..1cbbdfcf38 100644 --- a/lib/ssh/doc/src/ssh_app.xml +++ b/lib/ssh/doc/src/ssh_app.xml @@ -4,97 +4,351 @@ <appref> <header> <copyright> - <year>2012</year><year>2013</year> + <year>2012</year><year>2017</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_<*>.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_<*>.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 <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 <c>ssh</c> daemon. </p> - </section> + </section> + <section> + <title>Host Keys</title> + <p>RSA, DSA and ECDSA 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> + <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> - <title>AUTHORIZED KEYS</title> - <p>The authorized key 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. + <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> + <marker id="supported_algos"></marker> + <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-group14-sha256</item> + <item>diffie-hellman-group16-sha512</item> + <item>diffie-hellman-group18-sha512</item> + <item>(diffie-hellman-group1-sha1, retired: can be enabled with the <c>preferred_algorithms</c> option)</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> + <item>rsa-sha2-256</item> + <item>rsa-sha2-512</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]</item> + <item>[email protected]</item> + <item>aes128-ctr</item> + <item>aes192-ctr</item> + <item>aes256-ctr</item> + <item>aes128-cbc</item> + <item>3des-cbc</item> + <item>(AEAD_AES_128_GCM, not enabled per default)</item> + <item>(AEAD_AES_256_GCM, not enabled per default)</item> + </list> + <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso> + for more information regarding AEAD_AES_*_GCM. + </p> + <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> + </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 Kernel 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>Except</p> + <list type="bulleted"> + <item>8.1. diffie-hellman-group1-sha1. Disabled by default, can be enabled with the <c>preferred_algorithms</c> option.</item> + </list> + <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> - </section> + </item> + + <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-kex-sha2">Draft-ietf-curdle-ssh-kex-sha2 (work in progress)</url>, Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH). + <p>Deviations:</p> + <list type="bulleted"> + <item>The <c>diffie-hellman-group1-sha1</c> is not enabled by default, but is still supported and can be enabled + with the option <c>preferred-algorithms</c></item> + <item>The questionable sha1-based algorithms <c>diffie-hellman-group-exchange-sha1</c> and + <c>diffie-hellman-group14-sha1</c> are still enabled by default for compatibility with ancient clients and servers. + They can be disabled with the option <c>preferred-algorithms</c></item> + </list> + <p/> + </item> + + <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-rsa-sha2">Draft-ietf-curdle-rsa-sha2 (work in progress)</url>, Use of RSA Keys with SHA-2 256 and 512 in Secure Shell (SSH). + </item> + + <item><url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info">Draft-ietf-curdle-ssh-ext-info (work in progress)</url>, Extension Negotiation in Secure Shell (SSH). + <p>Implemented are:</p> + <list type="bulleted"> + <item>The Extension Negotiation Mechanism</item> + <item>The extension <c>server-sig-algs</c></item> + </list> + <p/> + </item> + + </list> - <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. - </p> - </section> </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..7b598494f7 100644 --- a/lib/ssh/doc/src/ssh_channel.xml +++ b/lib/ssh/doc/src/ssh_channel.xml @@ -5,87 +5,103 @@ <header> <copyright> <year>2009</year> - <year>2013</year> + <year>2016</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_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 STDLIB. + 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..98a1676ca4 100644 --- a/lib/ssh/doc/src/ssh_client_key_api.xml +++ b/lib/ssh/doc/src/ssh_client_key_api.xml @@ -5,120 +5,138 @@ <header> <copyright> <year>2012</year> - <year>2013</year> + <year>2016</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_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'{}} + | {#'ECPoint'{},{namedCurve,Curve::string()}}</c></p></item> + <tag><c>private_key() =</c></tag> + <item><p><c>#'RSAPrivateKey'{} + | #'DSAPrivateKey'{} + | #'ECPrivateKey'{}</c></p></item> + <tag><c>public_key_algorithm() =</c></tag> + <item><p><c>'ssh-rsa' | 'ssh-dss' + | 'rsa-sha2-256' | 'rsa-sha2-384' | 'rsa-sha2-512' + | 'ecdsa-sha2-nistp256' | 'ecdsa-sha2-nistp384' | 'ecdsa-sha2-nistp521' </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, DSA or ECDSA 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>. The option list given in + the <c>key_cb</c> option is available with the key <c>key_cb_private</c>.</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, DSA or ECDSA 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 - can be handled.</d> + <d>Host key algorithm.</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>. The option list given in + the <c>key_cb</c> option is available with the key <c>key_cb_private</c>.</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> + {ok, PrivateKey} | {error, Reason}</name> + <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 - can be handled.</d> + <d>Host key algorithm.</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>. The option list given in + the <c>key_cb</c> option is available with the key <c>key_cb_private</c>.</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_protocol.xml b/lib/ssh/doc/src/ssh_protocol.xml index 7288266cf7..a0032ab449 100644 --- a/lib/ssh/doc/src/ssh_protocol.xml +++ b/lib/ssh/doc/src/ssh_protocol.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2013</year><year>2013</year> + <year>2013</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -138,8 +138,6 @@ 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> - diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml index f7133e4ba5..c6808b95d1 100644 --- a/lib/ssh/doc/src/ssh_server_key_api.xml +++ b/lib/ssh/doc/src/ssh_server_key_api.xml @@ -5,86 +5,108 @@ <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'{}} + | {#'ECPoint'{},{namedCurve,Curve::string()}}</c></p></item> + <tag><c>private_key() =</c></tag> + <item><p><c>#'RSAPrivateKey'{} + | #'DSAPrivateKey'{} + | #'ECPrivateKey'{}</c></p></item> + <tag><c>public_key_algorithm() =</c></tag> + <item><p><c>'ssh-rsa' | 'ssh-dss' + | 'rsa-sha2-256' | 'rsa-sha2-384' | 'rsa-sha2-512' + | 'ecdsa-sha2-nistp256' | 'ecdsa-sha2-nistp384' | 'ecdsa-sha2-nistp521' </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 - 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> + <d>Host key algorithm.</d> + <v>DaemonOptions = proplists:proplist()</v> + <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>. The option list given in + the <c>key_cb</c> option is available with the key <c>key_cb_private</c>.</d> + <v>Key = private_key() | crypto:engine_key_ref()</v> + <d>Private key of the host matching the <c>Algorithm</c>. + It may be a reference to a 'ssh-rsa', rsa-sha2-* or 'ssh-dss' (NOT ecdsa) key stored in a loaded Engine.</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, DSA or ECDSA 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>. The option list given in + the <c>key_cb</c> option is available with the key <c>key_cb_private</c>.</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..f367560b5f 100644 --- a/lib/ssh/doc/src/ssh_sftp.xml +++ b/lib/ssh/doc/src/ssh_sftp.xml @@ -4,167 +4,258 @@ <erlref> <header> <copyright> - <year>2005</year><year>2014</year> + <year>2005</year><year>2017</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>reason()</c></tag> + <item> + <p>= <c>atom() | string() | tuple() </c>A description of the reason why an operation failed.</p> + <p> + The <c>atom()</c> value is formed from the sftp error codes in the protocol-level responses as defined in + <url href="https://tools.ietf.org/id/draft-ietf-secsh-filexfer-13.txt">draft-ietf-secsh-filexfer-13.txt</url> + section 9.1. + </p> + <p> + The codes are named as <c>SSH_FX_*</c> which are transformed into lowercase of the star-part. + E.g. the error code <c>SSH_FX_NO_SUCH_FILE</c> + will cause the <c>reason()</c> to be <c>no_such_file</c>. + </p> + <p>The <c>string()</c> reason is the error information from the server in case of an exit-signal. If that information is empty, the reason is the exit signal name. + </p> + <p>The <c>tuple()</c> reason are other errors like the <c>{exit_status,integer()}</c> if the exit status is not 0. + </p> + </item> + + <tag><c>ssh_connection_ref() =</c></tag> + <item><p><c>opaque()</c> - as returned by + <seealso marker="ssh#connect-3"><c>ssh:connect/3</c></seealso></p></item> + + <tag><c>timeout()</c></tag> + <item><p>= <c>infinity | integer()</c> in milliseconds. Default infinity.</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>, + no answer was received from the server within the expected time.</p> + <p>The request may have reached the server and may have been performed. + However, 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> + </type> + <desc><p>The <c><![CDATA[apread/4]]></c> function reads from a specified position, + combining the <seealso marker="#position-3"><c>position/3</c></seealso> and + <seealso marker="#aread-3"><c>aread/3</c></seealso> functions.</p> + </desc> + </func> + + <func> + <name>apwrite(ChannelPid, Handle, Position, Data) -> {async, N} | {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>N = term()</v> + </type> + <desc><p>The <c><![CDATA[apwrite/4]]></c> function writes to a specified position, + combining the <seealso marker="#position-3"><c>position/3</c></seealso> and + <seealso marker="#awrite-3"><c>awrite/3</c></seealso> functions.</p> + </desc> + </func> + + <func> + <name>aread(ChannelPid, Handle, 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> + </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, reason()}]]></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) -> {async, N} | {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>Reason = term()</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> </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, reason()}]]></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> </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> </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>. + </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> - <name>list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, Reason}</name> - <fsummary>List directory</fsummary> + + <func> + <name>list_dir(ChannelPid, Path) -></name> + <name>list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, reason()}</name> + <fsummary>Lists the directory.</fsummary> <type> <v>ChannelPid = pid()</v> <v>Path = string()</v> <v>Filenames = [Filename]</v> <v>Filename = string()</v> <v>Timeout = timeout()</v> - <v>Reason = term()</v> </type> <desc> <p>Lists the given directory on the server, returning the filenames as a list of strings.</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> + <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> + </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>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> + </type> + <desc> + <p>Creates a symbolic link pointing to <c><![CDATA[Target]]></c> with the + name <c><![CDATA[Name]]></c>. + </p> + </desc> + </func> + + <func> + <name>open(ChannelPid, File, Mode) -></name> + <name>open(ChannelPid, File, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> + <fsummary>Opens a file and returns a handle.</fsummary> <type> <v>ChannelPid = pid()</v> <v>File = string()</v> @@ -172,40 +263,39 @@ <v>Modeflag = read | write | creat | trunc | append | binary</v> <v>Timeout = timeout()</v> <v>Handle = term()</v> - <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, Timeout) -> {ok, Handle} | {error, Reason}</name> - <fsummary>Open a directory and return a handle</fsummary> + <name>opendir(ChannelPid, Path) -></name> + <name>opendir(ChannelPid, Path, Timeout) -> {ok, Handle} | {error, reason()}</name> + <fsummary>Opens a directory and returns a handle.</fsummary> <type> <v>ChannelPid = pid()</v> <v>Path = string()</v> <v>Timeout = timeout()</v> - <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> <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> + <name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> + <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> @@ -216,116 +306,87 @@ <v>DecryptResult = {ok,PlainBin,CryptoState} | {ok,PlainBin,CryptoState,ChunkSize}</v> <v>CloseFun = (fun(PlainBin,CryptoState) -> {ok,EncryptedBin})</v> <v>Timeout = timeout()</v> - <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 = <<"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, reason()}</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>Reason = term()</v> + <v>NewPosition = integer()</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, Timeout) -> {ok, Data} | eof | {error, Error}</name> - <fsummary>Read from an open file</fsummary> + <name>pread(ChannelPid, Handle, Position, Len) -></name> + <name>pread(ChannelPid, Handle, Position, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</name> + <fsummary>Reads from an open file.</fsummary> <type> <v>ChannelPid = pid()</v> <v>Handle = term()</v> @@ -333,289 +394,272 @@ <v>Len = integer()</v> <v>Timeout = timeout()</v> <v>Data = string() | binary()</v> - <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> - </desc> - </func> + <desc><p>The <c><![CDATA[pread/3,4]]></c> function reads from a specified position, + combining the <seealso marker="#position-3"><c>position/3</c></seealso> and + <seealso marker="#read-3"><c>read/3,4</c></seealso> functions.</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, Timeout) -> ok | {error, Error}</name> - <fsummary>Write to an open file</fsummary> + <name>pwrite(ChannelPid, Handle, Position, Data) -> ok</name> + <name>pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, reason()}</name> + <fsummary>Writes to an open file.</fsummary> <type> <v>ChannelPid = pid()</v> <v>Handle = term()</v> <v>Position = integer()</v> <v>Data = iolist()</v> <v>Timeout = timeout()</v> - <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> - </desc> + <desc><p>The <c><![CDATA[pwrite/3,4]]></c> function writes to a specified position, + combining the <seealso marker="#position-3"><c>position/3</c></seealso> and + <seealso marker="#write-3"><c>write/3,4</c></seealso> functions.</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> + <name>read(ChannelPid, Handle, Len) -></name> + <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</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>Reason = term()</v> + <v>Data = string() | binary()</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> </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.</p> </desc> </func> - <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> + + <func> + <name>read_file_info(ChannelPid, Name) -></name> + <name>read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, reason()}</name> + <fsummary>Gets information about a file.</fsummary> <type> <v>ChannelPid = pid()</v> <v>Name = string()</v> <v>Handle = term()</v> <v>Timeout = timeout()</v> <v>FileInfo = record()</v> - <v>Reason = term()</v> </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> + <p>Returns a <c><![CDATA[file_info]]></c> record from the file system object specified by + <c><![CDATA[Name]]></c> or <c><![CDATA[Handle]]></c>. See + <seealso marker="kernel:file#read_file_info-2">file:read_file_info/2</seealso> + for information about the record. + </p> + <p> + Depending on the underlying OS:es links might be followed and info on the final file, directory + etc is returned. See <seealso marker="#read_link_info-2">ssh_sftp::read_link_info/2</seealso> + on how to get information on links instead. + </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>Reason = term()</v> + <v>Target = string()</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>. + </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>Reason = term()</v> + <v>FileInfo = record()</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>. + See + <seealso marker="kernel:file#read_link_info-2">file:read_link_info/2</seealso> + for information about the record. + </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>Reason = term()</v> + <v>OldName = string()</v> + <v>NewName = string()</v> + <v>Timeout = timeout()</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>. + </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) -> + {ok, Pid} | {error, reason()|term()}</name> + + <name>start_channel(Host, Options) -></name> + <name>start_channel(Host, Port, Options) -> + {ok, Pid, ConnectionRef} | {error, reason()|term()}</name> + + <name>start_channel(TcpSocket) -></name> + <name>start_channel(TcpSocket, Options) -> + {ok, Pid, ConnectionRef} | {error, reason()|term()}</name> + + <fsummary>Starts an SFTP client.</fsummary> <type> - <v>ChannelPid = pid()</v> - <v>Name = string()</v> - <v>Target = string()</v> - <v>Reason = term()</v> + <v>Host = string()</v> + <v>ConnectionRef = ssh_connection_ref()</v> + <v>Port = integer()</v> + <v>TcpSocket = port()</v> + <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</c></d> + <v>Options = [{Option, Value}]</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>There are two ways to set a timeout for the underlying ssh connection:</p> + <list> + <item>If the connection timeout option <c>connect_timeout</c> is set, that value + is used also for the negotiation timeout and this option (<c>timeout</c>) is ignored.</item> + <item>Otherwise, this option (<c>timeout</c>) is used as the negotiation timeout + only and there is no connection timeout set</item> + </list> + <p>The value 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, reason()}</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> </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. The file is created if it does not exist + but 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>Writes file information from a <c><![CDATA[file_info]]></c> record to the + file specified by <c><![CDATA[Name]]></c>. See + <seealso marker="kernel:file#write_file_info-2">file:write_file_info/[2,3]</seealso> + for information about the record. </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..1be29b3b29 100644 --- a/lib/ssh/doc/src/ssh_sftpd.xml +++ b/lib/ssh/doc/src/ssh_sftpd.xml @@ -4,85 +4,92 @@ <erlref> <header> <copyright> - <year>2005</year><year>2013</year> + <year>2005</year><year>2016</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_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..d902df6848 100644 --- a/lib/ssh/doc/src/usersguide.xml +++ b/lib/ssh/doc/src/usersguide.xml @@ -4,34 +4,37 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2012</year><year>2013</year> + <year>2012</year><year>2016</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 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"/> + <xi:include href="configure_algos.xml"/> </part> diff --git a/lib/ssh/doc/src/using_ssh.xml b/lib/ssh/doc/src/using_ssh.xml index 46178d4018..ab307624e6 100644 --- a/lib/ssh/doc/src/using_ssh.xml +++ b/lib/ssh/doc/src/using_ssh.xml @@ -5,81 +5,88 @@ <header> <copyright> <year>2012</year> - <year>2013</year> + <year>2017</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>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,<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,<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,14 +231,81 @@ </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 = <<"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). --behaviour(ssh_subsystem). +-behaviour(ssh_daemon_channel). -record(state, { n, id, @@ -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,<0.54.0>} 3> </code> @@ -293,6 +383,7 @@ terminate(_Reason, _State) -> {ssh_msg, <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> |