diff options
Diffstat (limited to 'lib/ssh/doc/src')
-rw-r--r-- | lib/ssh/doc/src/Makefile | 62 | ||||
-rw-r--r-- | lib/ssh/doc/src/book.xml | 21 | ||||
-rw-r--r-- | lib/ssh/doc/src/configure_algos.xml | 429 | ||||
-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 | 1876 | ||||
-rw-r--r-- | lib/ssh/doc/src/part_notes.xml | 37 | ||||
-rw-r--r-- | lib/ssh/doc/src/ref_man.xml | 28 | ||||
-rw-r--r-- | lib/ssh/doc/src/specs.xml | 13 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh.xml | 1466 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_app.xml | 410 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_channel.xml | 422 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_client_channel.xml | 440 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_client_key_api.xml | 153 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_connection.xml | 559 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_protocol.xml | 10 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_server_channel.xml | 176 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_server_key_api.xml | 133 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftp.xml | 796 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftpd.xml | 76 | ||||
-rw-r--r-- | lib/ssh/doc/src/usersguide.xml | 29 | ||||
-rw-r--r-- | lib/ssh/doc/src/using_ssh.xml | 232 |
22 files changed, 5742 insertions, 1845 deletions
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile index 0e79d9979f..77fa356092 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-2018. 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% # @@ -37,27 +38,31 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) # Target Specs # ---------------------------------------------------- XML_APPLICATION_FILES = ref_man.xml -XML_REF3_FILES = ssh.xml \ - ssh_channel.xml \ - ssh_connection.xml \ +XML_REF3_FILES = \ + ssh.xml \ + ssh_client_channel.xml \ ssh_client_key_api.xml \ + ssh_connection.xml \ + ssh_server_channel.xml \ ssh_server_key_api.xml \ ssh_sftp.xml \ ssh_sftpd.xml \ XML_REF6_FILES = ssh_app.xml -XML_PART_FILES = part_notes.xml \ - usersguide.xml -XML_CHAPTER_FILES = 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 @@ -82,11 +87,18 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf +SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) + +TOP_SPECS_FILE = specs.xml + # ---------------------------------------------------- -# FLAGS +# FLAGS # ---------------------------------------------------- -XML_FLAGS += -DVIPS_FLAGS += +XML_FLAGS += +DVIPS_FLAGS += + +#SPECS_FLAGS = -I../../include -I../../../kernel/include +SPECS_FLAGS = -I../../../public_key/include -I../../../public_key/src -I../../.. # ---------------------------------------------------- # Targets @@ -107,19 +119,21 @@ html: images $(HTML_REF_MAN_FILE) clean clean_docs: rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) rm -f $(MAN3DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f $(SPECS_FILES) rm -f errs core *~ 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..fa45b1cb4c --- /dev/null +++ b/lib/ssh/doc/src/configure_algos.xml @@ -0,0 +1,429 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2017</year> + <year>2018</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> + <marker id="example_default_algorithms"/> + <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#type-preferred_algorithms_common_option">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#type-modify_algorithms_common_option">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..8444daf0cc 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>2018</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_client_channel">ssh_client_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..7e77c6a457 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>2018</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,1855 @@ <file>notes.xml</file> </header> +<section><title>Ssh 4.7.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Extended the undocumented <c>ssh_dbg</c> debug module + with an api for a circular trace buffer. This makes it + easy to record the last low-level events before an error + is detected. It is intended for solving difficult errors.</p> + <p> + Own Id: OTP-15020</p> + </item> + <item> + <p> + The key exchange methods + <c>'[email protected]'</c>, + <c>'curve25519-sha256'</c> and <c>'curve448-sha512'</c> + are implemented. The last two are defined in + https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves</p> + <p> + They all depends on that OpenSSL 1.1.1 or higher is used + as cryptolib.</p> + <p> + Own Id: OTP-15133 Aux Id: OTP-15240 </p> + </item> + <item> + <p> + The cipher '<c>[email protected]</c>' is now + supported if OpenSSL 1.1.1 or higher is used as + cryptolib.</p> + <p> + Own Id: OTP-15209 Aux Id: OTP-15164 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.7</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If the daemon port listener is restarted, it could + potentially fail with <c>eaddrinuse</c> if the timing is + unlucky. It will now retry and exponentially back off the + listener restart a few times before failing.</p> + <p> + Own Id: OTP-14955</p> + </item> + <item> + <p> + A channel callback module always got the module name as + reason in a call to terminate. Now it will get the proper + Reason, usually 'normal'.</p> + <p> + Own Id: OTP-15084</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The option <c>exec</c> has new option values defined to + make it much more easy to implement an own <c>exec</c> + server.</p> + <p> + An option called <c>exec</c> for daemons implementing the + handling of 'exec' requests has existed a long time but + has been undocumented. The old undocumented value - as + well as its behavior - is kept for compatibility EXCEPT + that error messages are changed and are sent as + "stderror" text.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-14851</p> + </item> + <item> + <p> + Updated ssh_connection:shell/2 documentation.</p> + <p> + Own Id: OTP-14880</p> + </item> + <item> + <p> + The experimental <c>ssh_dbg</c> module is completely + re-written. Its purpose is to make tracing and debugging + easier on deployed systems.</p> + <p> + Own Id: OTP-14896</p> + </item> + <item> + <p> + The SSH supervisor structure has been slightly changed. + This makes stopping the ssh application considerably + faster if there are open connections. This is important + in for example restarts.</p> + <p> + Own Id: OTP-14988</p> + </item> + <item> + <p> + The type specifications in SSH are completly reworked and + the following types are renamed:</p> + <p> + <c>ssh:ssh_connection_ref()</c> is changed to + <c>ssh:connection_ref()</c>, </p> + <p> + <c>ssh:ssh_daemon_ref()</c> is changed to + <c>ssh:daemon_ref()</c>,</p> + <p> + <c>ssh:ssh_channel_id()</c> is changed to + <c>ssh:channel_id()</c>.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15002 Aux Id: OTP-15030 </p> + </item> + <item> + <p> + The internal timer handling in SSH is now based on the + gen_statem timers.</p> + <p> + Own Id: OTP-15019</p> + </item> + <item> + <p> + Removed the undocumented and unused modules + <c>ssh_client_key.erl</c> and <c>ssh_server_key.erl</c>.</p> + <p> + Own Id: OTP-15028</p> + </item> + <item> + <p> + The Reference Manual pages are partly updated.</p> + <p> + The ssh page is now generated from specs and types, is + restructured and is partly rephrased.</p> + <p> + The ssh_channel, ssh_connection, ssh_client_key_api, + ssh_server_key_api and ssh_sftp pages are updated with + links, correct type names and some minor changes.</p> + <p> + Own Id: OTP-15030 Aux Id: OTP-15002 </p> + </item> + <item> + <p> + The behaviors <c>ssh_channel</c> and + <c>ssh_daemon_channel</c> are renamed to + <c>ssh_client_channel</c> and <c>ssh_server_channel</c> + respectively.</p> + <p> + The old modules are kept for compatibility but should + preferably be replaced when updating callback modules + referring them.</p> + <p> + Own Id: OTP-15041</p> + </item> + <item> + <p> + New test suite for channels.</p> + <p> + Own Id: OTP-15051</p> + </item> + <item> + <p> + The <c>rekey_limit</c> option could now set the max time + as well as the previously max data amount.</p> + <p> + Own Id: OTP-15069 Aux Id: ERL-617 </p> + </item> + <item> + <p> + Changed process exit supervision from links to monitors.</p> + <p> + Own Id: OTP-15082</p> + </item> + <item> + <p> + Better handling of misbehaving channel callback modules.</p> + <p> + Own Id: OTP-15083</p> + </item> + <item> + <p> + A new moduli file is generated. This file is used for the + recommended <c>diffie-hellman-group-exchange-sha256</c> + key exchange algorithm in SSH.</p> + <p> + Own Id: OTP-15113</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.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix rare spurios shutdowns of ssh servers when receiveing + <c>{'EXIT',_,normal}</c> messages.</p> + <p> + Own Id: OTP-15018</p> + </item> + <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.4.2.3</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> + </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.6</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <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.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 +1891,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..df37b0244f 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>2018</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,13 +29,14 @@ <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"/> <xi:include href="ssh.xml"/> - <xi:include href="ssh_channel.xml"/> + <xi:include href="ssh_client_channel.xml"/> + <xi:include href="ssh_server_channel.xml"/> <xi:include href="ssh_connection.xml"/> <xi:include href="ssh_client_key_api.xml"/> <xi:include href="ssh_server_key_api.xml"/> diff --git a/lib/ssh/doc/src/specs.xml b/lib/ssh/doc/src/specs.xml new file mode 100644 index 0000000000..acdbe2ddfd --- /dev/null +++ b/lib/ssh/doc/src/specs.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" ?> +<specs xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="../specs/specs_ssh.xml"/> + <xi:include href="../specs/specs_ssh_client_channel.xml"/> + <xi:include href="../specs/specs_ssh_client_key_api.xml"/> + <xi:include href="../specs/specs_ssh_connection.xml"/> + <xi:include href="../specs/specs_ssh_server_channel.xml"/> + <xi:include href="../specs/specs_ssh_server_key_api.xml"/> + <xi:include href="../specs/specs_ssh_sftp.xml"/> + <xi:include href="../specs/specs_ssh_sftpd.xml"/> +</specs> + + diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index 501668ca78..f238bf2ca8 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -4,482 +4,1260 @@ <erlref> <header> <copyright> - <year>2004</year><year>2014</year> + <year>2004</year><year>2018</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>This is the interface module for the <c>SSH</c> application. + The Secure Shell (SSH) Protocol is a protocol for secure remote login + and other secure network services over an insecure network. + See <seealso marker="ssh:SSH_app#supported">ssh(6)</seealso> for details of supported RFCs, versions, + algorithms and unicode handling. + </p> + <p>With the SSH application it is possible to start <i>clients</i> and to start <i>daemons</i> (servers). + </p> + <p>Clients are started with + <seealso marker="#connect/2">connect/2</seealso>, + <seealso marker="#connect/3">connect/3</seealso> or + <seealso marker="#connect/4">connect/4</seealso>. They open an encrypted connection on top of TCP/IP. + In that encrypted connection one or more channels could be opened with + <seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/2,4</seealso>. + </p> + <p>Each channel is an isolated "pipe" between a client-side process and a server-side process. Thoose process + pairs could handle for example file transfers (sftp) or remote command execution (shell, exec and/or cli). + If a custom shell is implemented, the user of the client could execute the special commands remotely. Note that + the user is not necessarily a human but probably a system interfacing the SSH app. + </p> + <p>A server-side subssystem (channel) server is requested by the client with + <seealso marker="ssh_connection#subsystem/4">ssh_connection:subsystem/4</seealso>. + </p> + <p>A server (daemon) is started with + <seealso marker="#daemon/2">daemon/1</seealso>, + <seealso marker="#daemon/2">daemon/2</seealso> or + <seealso marker="#daemon/2">daemon/3</seealso>. + Possible channel handlers (subsystems) are declared with the + <seealso marker="#type-subsystem_daemon_option">subsystem</seealso> option when the daemon is started. + </p> + <p>To just run a shell on a remote machine, there are functions that bundles the needed + three steps needed into one: + <seealso marker="#shell/1">shell/1,2,3</seealso>. + Similarily, to just open an sftp (file transfer) connection to a remote machine, the simplest way is to use + <seealso marker="ssh_sftp#start_channel/1">ssh_sftp:start_channel/1,2,3</seealso>. + </p> + <p>To write your own client channel handler, use the behaviour + <seealso marker="ssh_client_channel">ssh_client_channel</seealso>. For server channel handlers use + <seealso marker="ssh_server_channel">ssh_server_channel</seealso> behaviour (replaces ssh_daemon_channel). + </p> + <p>Both clients and daemons accepts options that controls the exact behaviour. Some options are common to both. + The three sets are called + <seealso marker="#type-client_options">Client Options</seealso>, + <seealso marker="#type-daemon_options">Daemon Options</seealso> and + <seealso marker="#type-common_options">Common Options</seealso>. + </p> + <p>The descriptions of the options uses the + <seealso marker="doc/reference_manual:typespec">Erlang Type Language</seealso> with explaining text. + </p> + <note> + <p>The <seealso marker="users_guide">User's Guide</seealso> has examples and a + <seealso marker="using_ssh">Getting Started</seealso> + section. + </p> + </note> </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> - <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() = [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> + <title>Keys and files</title> + <p>A number of objects must be present for the SSH application to work. + Thoose objects are per default stored in files. + The default names, paths and file formats are the same as for + <url href="http://www.openssh.com">OpenSSH</url>. Keys could be generated with the <c>ssh-keygen</c> + program from OpenSSH. See the + <seealso marker="using_ssh#running-an-erlang-ssh-daemon">User's Guide</seealso>. + </p> - <funcs> - - <func> - <name>close(ConnectionRef) -> ok </name> - <fsummary>Closes an SSH connection</fsummary> - <type> - <v>ConnectionRef = ssh_connection_ref()</v> - </type> - <desc><p>Closes an SSH connection.</p> + <p>The paths could easily be changed by options: + <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso> and + <seealso marker="#type-system_dir_daemon_option"><c>system_dir</c></seealso>. + </p> + <p>A completly different storage could be interfaced by writing call-back modules + using the behaviours + <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and/or + <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>. + A callback module is installed with the option + <seealso marker="#type-key_cb_common_option"><c>key_cb</c></seealso> + to the client and/or the daemon. + </p> + + <section> + <title>Daemons</title> + <p>The keys are by default stored in files:</p> + <list> + <item>Mandatory: one or more <i>Host key(s)</i>, both private and public. Default is to + store them in the directory <c>/etc/ssh</c> in the files + <list> + <item><c>ssh_host_dsa_key</c> and <c>ssh_host_dsa_key.pub</c></item> + <item><c>ssh_host_rsa_key</c> and <c>ssh_host_rsa_key.pub</c></item> + <item><c>ssh_host_ecdsa_key</c> and <c>ssh_host_ecdsa_key.pub</c></item> + </list> + <p>The host keys directory could be changed with the option + <seealso marker="#type-system_dir_daemon_option"><c>system_dir</c></seealso>.</p> + </item> + <item>Optional: one or more <i>User's public key</i> in case of <c>publickey</c> authorization. + Default is to store them concatenated in the file <c>.ssh/authorized_keys</c> in the user's home directory. + <p>The user keys directory could be changed with the option + <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso>.</p> + </item> + </list> + </section> + + <section> + <title>Clients</title> + <p>The keys and some other data are by default stored in files in the directory <c>.ssh</c> + in the user's home directory.</p> + <p>The directory could be changed with the option + <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso>. + </p> + <list> + <item>Optional: a list of <i>Host public key(s)</i> for previously connected hosts. This list + is handled by the SSH application without any need of user assistance. The default + is to store them in the file <c>known_hosts</c>. + <p>The + <seealso marker="#type-host_accepting_client_options">host_accepting_client_options()</seealso> + are associated with this list of keys. + </p> + </item> + <item>Optional: one or more <i>User's private key(s)</i> in case of <c>publickey</c> authorization. + The default files are + <list> + <item><c>id_dsa</c> and <c>id_dsa.pub</c></item> + <item><c>id_rsa</c> and <c>id_rsa.pub</c></item> + <item><c>id_ecdsa</c> and <c>id_ecdsa.pub</c></item> + </list> + </item> + </list> + </section> + + </section> + + <!-- + ================================================================ + = Data types = + ================================================================ + --> + + <datatypes> + + <datatype_title>Client Options</datatype_title> + + <datatype> + <name name="client_options"/> + <name name="client_option"/> + <desc> + <p>Options for <seealso marker="#connect/3">clients</seealso>. + The individual options are further explained below or by following the hyperlinks. + </p> </desc> - </func> - - <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> - <type> - <v>Host = string()</v> - <v>Port = integer()</v> - <d>The default is <c><![CDATA[22]]></c>, 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> - </type> + </datatype> + + <datatype> + <name name="pref_public_key_algs_client_option"/> + <desc> + <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 the list returned by + <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> + <p>See also the option <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso> + for specifying the path to the user's keys. + </p> + </desc> + </datatype> + + <datatype> + <name name="pubkey_passphrase_client_options"/> + <desc> + <p>If the user's DSA, RSA or ECDSA key is protected by a passphrase, it can be + supplied with thoose options. + </p> + </desc> + </datatype> + + <datatype> + <name name="host_accepting_client_options"/> + <name name="accept_hosts"/> + <name name="fp_digest_alg"/> + <name name="accept_callback"/> + <name name="fingerprint"/> <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> <taglist> - <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag> - <item> IP version to use.</item> - <tag><c><![CDATA[{user_dir, string()}]]></c></tag> + <tag><c>silently_accept_hosts</c></tag> <item> - <p>Sets the user directory i.e. the directory containing - ssh configuration files for the user such as - <c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa, - id_dsa]]></c> and - <c><![CDATA[authorized_key]]></c>. Defaults to the - directory normally referred to as - <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 - supplied with this option. + <p>This option guides the <c>connect</c> function on 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 the option <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso> + for specifying the path to the file <c>known_hosts</c> where previously accepted Host Keys are recorded. + See also the option + <seealso marker="#type-key_cb_common_option">key_cb</seealso> + for the general way to handle keys. </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> preserves the default behaviour of asking the user on stdio. + </item> + <item>An <c>accept_callback()</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 as a + result 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, accept_callback}</c>. The <c>HashAlgoSpec</c> + specifies which hash algorithm + shall be used to calculate the fingerprint used in the call of the <c>accept_callback()</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>accept_callback()</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[{rsa_pass_phrase, string()}]]></c></tag> + + <tag><c>user_interaction</c></tag> <item> - <p>If the user rsa key is protected by a passphrase it can be - supplied with this option. - </p> + <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.</p> + <p>Even if user interaction is allowed it can be + 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> + <p>Defaults to <c>true</c>.</p> </item> - <tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag> + + <tag><c>save_accepted_host</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 <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 + <seealso marker="#type-key_cb_common_option"><c>key_cb</c></seealso> + is not present, the key is saved in the file "known_hosts". See option + <seealso marker="#type-user_dir_common_option"><c>user_dir</c></seealso> for + the location of that file. </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> + <p>Defaults to <c>true</c></p> </item> - <tag><c><![CDATA[{user_interaction, boolean()}]]></c></tag> - <item> - <p>If false disables the client to connect to the server - if any user interaction is needed such as accepting that - the server will be added to the <c>known_hosts</c> file or - supplying a password. Defaults to true. - 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> - </item> - <tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></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> - </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> - </item> - <tag><c><![CDATA[{connect_timeout, timeout()}]]></c></tag> + + <tag><c>quiet_mode</c></tag> <item> - <p>Sets a timeout on the transport layer - connection. Defaults to <c>infinity</c>.</p> + <p>If <c>true</c>, the client does not print anything on authorization.</p> + <p>Defaults to <c>false</c></p> </item> - <tag><c><![CDATA[{user, string()}]]></c></tag> + </taglist> + </desc> + </datatype> + + <datatype> + <name name="authentication_client_options"/> + <desc> + <taglist> + <tag><c>user</c></tag> <item> - <p>Provides a user name. If this option is not given, ssh + <p>Provides the 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> + + <tag><c>password</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> - <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> - </item> - <tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag> - <item> - <p>If true, the client will not print out anything on authorization.</p> - </item> + </taglist> + </desc> + </datatype> - <tag><c><![CDATA[{id_string, random | string()}]]></c></tag> - <item> - <p>The string that the client presents to a connected server initially. The default value is "Erlang/VSN" where VSN is the ssh application version number. - </p> - <p>The value <c>random</c> will cause a random string to be created at each connection attempt. This is to make it a bit more difficult for a malicious peer to find the ssh software brand and version. - </p> - </item> + <datatype> + <name name="diffie_hellman_group_exchange_client_option"/> + <desc> + <p>Sets the three diffie-hellman-group-exchange parameters that guides the connected server in choosing a group. + See + <url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url> + for the details. The default value is <c>{1024, 6144, 8192}</c>. + </p> + </desc> + </datatype> - <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[{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> - </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> + <datatype> + <name name="connect_timeout_client_option"/> + <desc> + <p>Sets a timeout on the transport layer connect time. + For <seealso marker="kernel:gen_tcp"><c>gen_tcp</c></seealso> the time is in milli-seconds and the default + value is <c>infinity</c>. + </p> + <p>See the parameter <c>Timeout</c> in <seealso marker="#connect/4">connect/4</seealso> for + a timeout of the negotiation phase. + </p> + </desc> + </datatype> - <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> - <p>The default behaviour is ignore the message. - To get a printout for each message with <c>AlwaysDisplay = true</c>, use for example <c>{ssh_msg_debug_fun, fun(_,true,M,_)-> io:format("DEBUG: ~p~n", [M]) end}</c></p> - </item> + <datatype> + <name name="recv_ext_info_client_option"/> + <desc> + <p>Make the client tell the server that the client accepts extension negotiation, that is, + include <c>ext-info-c</c> in the kexinit message sent. See + <url href="https://tools.ietf.org/html/rfc8308">RFC 8308</url> + for details and <seealso marker="SSH_app#supported-ext-info">ssh(6)</seealso> + for a list of currently implemented extensions. + </p> + <p> + Default value is <c>true</c> which is compatible with other implementations not supporting ext-info. + </p> + </desc> + </datatype> - </taglist> - </desc> - </func> + <!--................................................................--> + <datatype_title>Daemon Options (Server Options)</datatype_title> - <func> - <name>connection_info(ConnectionRef, [Option]) ->[{Option, - 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> - </type> + <datatype> + <name name="daemon_options"/> + <name name="daemon_option"/> <desc> - <p> Retrieves information about a connection. - </p> + <p>Options for <seealso marker="#daemon/1">daemons</seealso>. + The individual options are further explained below or by following the hyperlinks. + </p> </desc> - </func> + </datatype> + - <func> - <name>daemon(Port) -> </name> - <name>daemon(Port, Options) -> </name> - <name>daemon(HostAddress, Port, 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>Options = [{Option, Value}]</v> - <v>Option = atom()</v> - <v>Value = term()</v> - </type> + <datatype> + <name name="subsystem_daemon_option"/> + <name name="subsystem_spec"/> + <desc> + <p>Defines a subsystem in the daemon.</p> + <p>The <c>subsystem_name</c> is the name that a client requests to start with for example + <seealso marker="ssh_connection#subsystem/4">ssh_connection:subsystem/4</seealso>. + </p> + <p>The <c>channel_callback</c> is the module that implements the + <seealso marker="ssh_server_channel">ssh_server_channel</seealso> (replaces ssh_daemon_channel) + behaviour in the daemon. See the section + <seealso marker="using_ssh#usersguide_creating_a_subsystem">Creating a Subsystem</seealso> + in the User's Guide for more information and an example. + </p> + <p>If the subsystems option is not present, the value of <c>ssh_sftpd:subsystem_spec([])</c> is used. + This enables the sftp subsystem by default. + The option can be set to the empty list if you do not want the daemon to run any subsystems.</p> + </desc> + </datatype> + + <datatype> + <name name="shell_daemon_option"/> + <name name="'shell_fun/1'"/> + <name name="'shell_fun/2'"/> + <desc> + <p>Defines the read-eval-print loop used in a daemon when a shell is requested by the client. + The default is to use the Erlang shell: <c><![CDATA[{shell, start, []}]]></c> + </p> + <p>See the option <seealso marker="#type-exec_daemon_option"><c>exec</c></seealso> + for a description of how the daemon execute exec-requests depending on + the shell- and exec-options.</p> + </desc> + </datatype> + + <datatype> + <name name="exec_daemon_option"/> + <name name="'exec_fun/1'"/> + <name name="'exec_fun/2'"/> + <name name="'exec_fun/3'"/> + <name name="exec_result"/> <desc> - <p>Starts a server listening for SSH connections on the given - port.</p> - <p>Options are:</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> - <tag><c><![CDATA[{subsystems, [subsystem_spec()]}]]></c></tag> + <p>This option changes how the daemon execute exec-requests from clients. The term in the return value + is formatted to a string if it is a non-string type. No trailing newline is added in the ok-case but in the + error case.</p> + <p>Error texts are returned on channel-type 1 which usually is piped to <c>stderr</c> on e.g Linux systems. + Texts from a successful execution will in similar manner be piped to <c>stdout</c>. The exit-status code + is set to 0 for success and -1 for errors. The exact results presented on the client side depends on the + client and the client's operating system. + </p> + <p>The option cooperates with the daemon-option <seealso marker="#type-shell_daemon_option"><c>shell</c></seealso> + in the following way:</p> + <taglist> + <tag>1. If the exec-option is present (the shell-option may or may not be present):</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>The exec-option fun is called with the same number of parameters as the arity of the fun, + and the result is returned to the client. + </p> </item> - <tag><c><![CDATA[{shell, {Module, Function, Args} | - fun(string() = User) - > pid() | fun(string() = User, - ip_address() = PeerAddr) -> pid()}]]></c></tag> + + <tag>2. If the exec-option is absent, but a shell-option is present with the default Erlang shell:</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>The default Erlang evaluator is used and the result is returned to the client.</p> </item> - <tag><c><![CDATA[{ssh_cli, {channel_callback(), - channel_init_args()} | no_cli}]]></c></tag> + + <tag>3. If the exec-option is absent, but a shell-option is present that is not the default Erlang shell:</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>The exec-request is not evaluated and an error message is returned to the client.</p> </item> - <tag><c><![CDATA[{user_dir, String}]]></c></tag> + + <tag>4. If neither the exec-option nor the shell-option is present:</tag> <item> - <p>Sets the user directory i.e. the directory containing - ssh configuration files for the user such as - <c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa, - id_dsa]]></c> and - <c><![CDATA[authorized_key]]></c>. Defaults to the - directory normally referred to as - <c><![CDATA[~/.ssh]]></c> </p> + <p>The default Erlang evaluator is used and the result is returned to the client.</p> </item> - <tag><c><![CDATA[{system_dir, string()}]]></c></tag> + </taglist> + <p>If a custom CLI is installed (see the option <seealso marker="#type-ssh_cli_daemon_option"><c>ssh_cli</c></seealso>) + the rules above are replaced by thoose implied by the custom CLI. + </p> + <note> + <p>The exec-option has existed for a long time but has not previously been documented. The old + definition and behaviour are retained but obey the rules 1-4 above if conflicting. + The old and undocumented style should not be used in new programs.</p> + </note> + </desc> + </datatype> + + <datatype> + <name name="ssh_cli_daemon_option"/> + <desc> + <p>Provides your own CLI implementation in a daemon.</p> + <p>It is a channel callback module that implements a shell + and command execution. The shell's read-eval-print loop can be customized, using the + option <seealso marker="#type-shell_daemon_option"><c>shell</c></seealso>. This means less work than implementing + an own CLI channel. If <c>ssh_cli</c> is set to <c>no_cli</c>, the CLI channels + like <seealso marker="#type-shell_daemon_option"><c>shell</c></seealso> + and <seealso marker="#type-exec_daemon_option"><c>exec</c></seealso> + are disabled and only subsystem channels are allowed.</p> + </desc> + </datatype> + + <datatype> + <name name="authentication_daemon_options"/> + <name name="prompt_texts"/> + <name name="kb_int_tuple"/> + <name name="kb_int_fun_3"/> + <name name="pwdfun_2"/> + <name name="pwdfun_4"/> + <desc> + <taglist> + <tag><marker id="type-system_dir_daemon_option"/><c>system_dir</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>/etc/ssh</c>.</p> + <p>For security reasons, this directory is normally accessible only to the root user.</p> + <p>See also the option + <seealso marker="#type-key_cb_common_option">key_cb</seealso> + for the general way to handle keys. + </p> </item> - <tag><c><![CDATA[{auth_methods, string()}]]></c></tag> + + <tag><c>auth_method_kb_interactive_data</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 - <c><![CDATA["publickey,keyboard-interactive,password"]]></c></p> + <p>Sets the text strings that the daemon sends to the client for presentation to the user when + using <c>keyboard-interactive</c> authentication.</p> + <p>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> + + <tag><c>user_passwords</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> + + <tag><c>password</c></tag> <item> - <p>Provide a global password that will authenticate any - user. From a security perspective this option makes - the server very vulnerable.</p> + <p>Provides a global password that authenticates any user.</p> + <warning> + <p>Intended to facilitate testing.</p> + <p>From a security perspective this option makes the server very vulnerable.</p> + </warning> </item> - <tag><c><![CDATA[{pwdfun, fun(User::string(), password::string()) -> boolean()}]]></c></tag> + + <tag><c>pwdfun</c> with <c>pwdfun_4()</c></tag> <item> - <p>Provide a function for password validation. This is called - with user and password as strings, and should return - <c><![CDATA[true]]></c> if the password is valid and - <c><![CDATA[false]]></c> otherwise.</p> + <p>Provides a function for password validation. This could used for calling an external system or handeling + passwords stored as hash values. + </p> + <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>.</p> + <p>To facilitate for instance 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>. + </p> + + <p>The fun should return: + </p> + <list type="bulleted"> + <item><c>true</c> if the user and password is valid</item> + <item><c>false</c> if the user or password is invalid</item> + <item><c>disconnect</c> if a SSH_MSG_DISCONNECT message should be sent immediately. It will + be followed by a close of the underlying tcp connection.</item> + <item><c>{true, NewState:any()}</c> if the user and password is valid</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. The return value <c>disconnect</c> is useful for this.</p> </item> - <tag><c><![CDATA[{negotiation_timeout, integer()}]]></c></tag> + <tag><c>pwdfun</c> with <c>pwdfun_2()</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> + <p>Provides a function for password validation. This function is called with user and password + as strings, and returns:</p> + <list type="bulleted"> + <item><c>true</c> if the user and password is valid</item> + <item><c>false</c> if the user or password is invalid</item> + </list> + <p>This variant is kept for compatibility.</p> </item> + </taglist> + </desc> + </datatype> - <tag><c><![CDATA[{max_sessions, pos_integer()}]]></c></tag> + <datatype> + <name name="diffie_hellman_group_exchange_daemon_option"/> + <name name="explicit_group"/> + <name name="explicit_group_file"/> + <name name="ssh_moduli_file"/> + <desc> + <taglist> + <tag><c>dh_gex_groups</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>Defines the groups the server may choose among when diffie-hellman-group-exchange is negotiated. + See + <url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url> + for details. The three variants of this option are: </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. + <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>dh_gex_limits</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>Note that if <c>parallel_login</c> is <c>false</c>, only one client at a time may be in the authentication phase. + <p>The default value is <c>{0,infinity}</c>. </p> - <p>As default, the option is not set. This means that the number is not limited. + <p>If <c>MaxUsed < MinUsed</c> in a key exchange, it will fail with a disconnect. </p> + <p>See + <url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url> + for the function of the Max and Min values.</p> </item> + </taglist> + </desc> + </datatype> - <tag><c><![CDATA[{parallel_login, boolean()}]]></c></tag> + <datatype> + <name name="negotiation_timeout_daemon_option"/> + <desc> + <p>Maximum time in milliseconds for the authentication negotiation. + Defaults to 120000 ms (2 minutes). If the client fails to log in within this time, + the connection is closed. + </p> + </desc> + </datatype> + + <datatype> + <name name="hardening_daemon_options"/> + <desc> + <taglist> + <tag><c>max_sessions</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>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>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>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>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>By default, this option is not set. This means that the number is not limited. </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> - </warning> </item> - <tag><c><![CDATA[{minimal_remote_max_packet_size, non_negative_integer()}]]></c></tag> + <tag><c>max_channels</c></tag> <item> - <p>The least maximum packet size that the daemon will accept in channel open requests from the client. The default value is 0. + <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[{id_string, random | string()}]]></c></tag> + <tag><c>parallel_login</c></tag> <item> - <p>The string the daemon will present to a connecting peer initially. The default value is "Erlang/VSN" where VSN is the ssh application version number. + <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>The value <c>random</c> will cause a random string to be created at each connection attempt. This is to make it a bit more difficult for a malicious peer to find the ssh software brand and version. + <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, 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> - <tag><c><![CDATA[{key_cb, atom()}]]></c></tag> + <tag><c>minimal_remote_max_packet_size</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>The least maximum packet size that the daemon will accept in channel open requests from the client. + The default value is 0. </p> </item> - <tag><c><![CDATA[{fd, file_descriptor()}]]></c></tag> + + </taglist> + </desc> + </datatype> + + <datatype> + <name name="callbacks_daemon_options"/> + <desc> + <taglist> + <tag><c>connectfun</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>Provides a fun to implement your own logging when a user authenticates to the server.</p> + </item> + + <tag><c>failfun</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> + </taglist> + </desc> + </datatype> + + <datatype> + <name name="send_ext_info_daemon_option"/> + <desc> + <p>Make the server (daemon) tell the client that the server accepts extension negotiation, that is, + include <c>ext-info-s</c> in the kexinit message sent. See + <url href="https://tools.ietf.org/html/rfc8308">RFC 8308</url> + for details and <seealso marker="SSH_app#supported-ext-info">ssh(6)</seealso> + for a list of currently implemented extensions. + </p> + <p>Default value is <c>true</c> which is compatible with other implementations not supporting ext-info. + </p> + </desc> + </datatype> + + + <!--................................................................--> + <datatype_title>Options common to clients and daemons</datatype_title> + <datatype> + <name name="common_options"/> + <name name="common_option"/> + <desc><p>The options above can be used both in clients and in daemons (servers). They are further explained below.</p> + </desc> + </datatype> + + <datatype> + <name name="user_dir_common_option"/> + <desc> + <p>Sets the user directory. That is, the directory containing <c>ssh</c> configuration + files for the user, such as + <c>known_hosts</c>, <c>id_rsa</c>, <c>id_dsa</c>>, <c>id_ecdsa</c> and <c>authorized_key</c>. + Defaults to the directory normally referred to as <c>~/.ssh</c>. + </p> + <p>See also the option + <seealso marker="#type-key_cb_common_option">key_cb</seealso> + for the general way to handle keys. + </p> + </desc> + </datatype> + + <datatype> + <name name="profile_common_option"/> + <desc> + <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> + </desc> + </datatype> + + <datatype> + <name name="max_idle_time_common_option"/> + <desc> + <p>Sets a time-out on a connection when no channels are active. Defaults to <c>infinity</c>.</p> + </desc> + </datatype> + + <datatype> + <name name="rekey_limit_common_option"/> + <name name="limit_bytes"/> + <name name="limit_time"/> + <desc> + <p>Sets the limit when rekeying is to be initiated. Both the max time and max amount of data + could be configured: + </p> + <list> + <item><c>{Minutes, Bytes}</c> initiate rekeying when any of the limits are reached.</item> + <item><c>Bytes</c> initiate rekeying when <c>Bytes</c> number of bytes are transferred, + or at latest after one hour.</item> + </list> + <p>When a rekeying is done, both the timer and the byte counter are restarted. + Defaults to one hour and one GByte.</p> + <p>If <c>Minutes</c> is set to <c>infinity</c>, no rekeying will ever occur due to that max time has passed. + Setting <c>Bytes</c> to <c>infinity</c> will inhibit rekeying after a certain amount of data has been transferred. + If the option value is set to <c>{infinity, infinity}</c>, no rekeying will be initiated. Note that rekeying initiated + by the peer will still be performed.</p> + </desc> + </datatype> + + <datatype> + <name name="key_cb_common_option"/> + <desc> + <p>Module implementing the behaviour + <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and/or + <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> + <p>The <c>Opts</c> defaults to <c>[]</c> when only the <c>Module</c> is specified. + </p> + <p>The default value of this option is <c>{ssh_file, []}</c>. + </p> + <p>A call to the call-back function <c>F</c> will be</p> + <code> + Module:F(..., [{key_cb_private,Opts}|UserOptions]) + </code> + <p>where <c>...</c> are arguments to <c>F</c> as in + <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> and/or + <seealso marker="ssh_server_key_api">ssh_server_key_api</seealso>. + The <c>UserOptions</c> are the options given to <c>ssh:connect</c>, <c>ssh:shell</c> or <c>ssh:daemon</c>. + </p> + + </desc> + </datatype> + + <datatype> + <name name="disconnectfun_common_option"/> + <desc> + <p>Provides a fun to implement your own logging when the peer disconnects.</p> + </desc> + </datatype> + + <datatype> + <name name="unexpectedfun_common_option"/> + <desc> + <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> + </desc> + </datatype> + + <datatype> + <name name="ssh_msg_debug_fun_common_option"/> + <desc> + <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 + <url href="https://tools.ietf.org/html/rfc4253#section-11.3">RFC 4253, section 11.3</url>. + The <seealso marker="#type-connection_ref"><c>connection_ref()</c></seealso> is the reference + to the connection on which the message arrived. + The return value from the fun is not checked. + </p> + <p>The default behaviour is ignore the message. + To get a printout for each message with <c>AlwaysDisplay = true</c>, + use for example <c>{ssh_msg_debug_fun, fun(_,true,M,_)-> io:format("DEBUG: ~p~n", [M]) end}</c></p> + </desc> + </datatype> + + <datatype> + <name name="id_string_common_option"/> + <desc> + <p>The string the daemon will present to a connecting peer initially. + The default value is "Erlang/VSN" where VSN is the ssh application version number. + </p> + <p>The value <c>random</c> will cause a random string to be created at each connection attempt. + This is to make it a bit more difficult for a malicious peer to find the ssh software brand and version. + </p> + <p>The value <c>{random, Nmin, Nmax}</c> will make a random string with at least <c>Nmin</c> characters and + at most <c>Nmax</c> characters. + </p> + </desc> + </datatype> + + <datatype> + <name name="preferred_algorithms_common_option"/> + <name name="algs_list"/> + <name name="alg_entry"/> + <name name="kex_alg"/> + <name name="pubkey_alg"/> + <name name="cipher_alg"/> + <name name="mac_alg"/> + <name name="compression_alg"/> + <name name="double_algs"/> + + <desc> + <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> + + <p>If an algorithm name occurs more than once in a list, the behaviour is undefined. The tags in the property lists + are also assumed to occur at most one time. + </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> + </desc> + </datatype> + + <datatype> + <name name="modify_algorithms_common_option"/> + <name name="modify_algs_list"/> + <desc> + <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>Provide a fun to implement your own logging when a user authenticates to the server.</p> + <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> - <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>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> - - <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> - <p>The default behaviour is ignore the message. - To get a printout for each message with <c>AlwaysDisplay = true</c>, use for example <c>{ssh_msg_debug_fun, fun(_,true,M,_)-> io:format("DEBUG: ~p~n", [M]) end}</c></p> + <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> + </desc> + </datatype> - </taglist> - </desc> + + <datatype> + <name name="inet_common_option"/> + <desc> + <p>IP version to use when the host address is specified as <c>any</c>.</p> + </desc> + </datatype> + + <datatype> + <name name="auth_methods_common_option"/> + <desc> + <p>Comma-separated string that determines which authentication methods that the client shall + support and in which order they are tried. Defaults to <c>"publickey,keyboard-interactive,password"</c> + </p> + <p>Note that the client is free to use any order and to exclude methods. + </p> + </desc> + </datatype> + + <datatype> + <name name="fd_common_option"/> + <desc> + <p>Allows an existing file-descriptor to be used (passed on to the transport protocol).</p> + </desc> + </datatype> + + <!--................................................................--> + <datatype_title>Other data types</datatype_title> + + <datatype> + <name name="host"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="ip_port"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="mod_args"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="mod_fun_args"/> + <desc> + </desc> + </datatype> + + <datatype> + <name name="open_socket"/> + <desc> + <p>The socket is supposed to be result of a <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> + or a <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso>. The socket must be in passive + mode (that is, opened with the option <c>{active,false})</c>. + </p> + </desc> + </datatype> + + <datatype> + <name name="daemon_ref"/> + <desc> + <p>Opaque data type representing a daemon.</p> + <p>Returned by the functions <seealso marker="ssh#daemon-1"><c>daemon/1,2,3</c></seealso>.</p> + </desc> + </datatype> + + <datatype> + <name>connection_ref()</name> + <desc> + <p>Opaque data type representing a connection between a client and a server (daemon).</p> + <p>Returned by the functions + <seealso marker="ssh#connect-3"><c>connect/2,3,4</c></seealso> and + <seealso marker="ssh_sftp#start_channel-2"><c>ssh_sftp:start_channel/2,3</c></seealso>. + </p> + </desc> + </datatype> + + <datatype> + <name name="channel_id"/> + <desc> + <p>Opaque data type representing a channel inside a connection.</p> + <p>Returned by the functions + <seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/2,4</seealso>. + </p> + </desc> + </datatype> + + + <datatype> + <name>opaque_client_options</name> + <name>opaque_daemon_options</name> + <name>opaque_common_options</name> + <desc> + <marker id="type-opaque_client_options"/> + <marker id="type-opaque_daemon_options"/> + <marker id="type-opaque_common_options"/> + <p>Opaque types that define experimental options that are not to be used in products.</p> + </desc> + </datatype> + </datatypes> + +<!-- + ================================================================ + = Function definitions = + ================================================================ +--> + + <funcs> + +<!-- CLOSE/1 --> + <func> + <name name="close" arity="1"/> + <fsummary>Closes an SSH connection.</fsummary> + <desc><p>Closes an SSH connection.</p></desc> </func> + +<!-- CONNECT/2 etc --> + <func> + <name>connect(Host, Port, Options) -> Result </name> + <name>connect(Host, Port, Options, NegotiationTimeout) -> Result </name> + <name>connect(TcpSocket, Options) -> Result</name> + <name>connect(TcpSocket, Options, NegotiationTimeout) -> Result</name> + <fsummary>Connects to an SSH server.</fsummary> + <type> + <v>Host = <seealso marker="#type-host">host()</seealso></v> + <v>Port = <seealso marker="kernel:inet#type-port_number">inet:port_number()</seealso></v> + <v>Options = <seealso marker="#type-client_options">client_options()</seealso></v> + <v>TcpSocket = <seealso marker="#type-open_socket">open_socket()</seealso></v> + <v>NegotiationTimeout = timeout()</v> + <v>Result = {ok, <seealso marker="#type-connection_ref">connection_ref()</seealso>} | {error, term()}</v> + </type> + <desc> + <p>Connects to an SSH server at the <c>Host</c> on <c>Port</c>. + </p> + <p>As an alternative, an already open TCP socket could be passed to the function in <c>TcpSocket</c>. + The SSH initiation and negotiation will be initiated on that one with the SSH that should be at the + other end. + </p> + <p>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>The <c>NegotiationTimeout</c> is in milli-seconds. The default value is <c>infinity</c>. + For connection timeout, use the option + <seealso marker="#type-connect_timeout_client_option"><c>connect_timeout</c></seealso>. + </p> + </desc> + </func> +<!-- CONNECTION_INFO/1, CONNECTION_INFO/2 --> + <func> + <name name="connection_info" arity="2"/> + <fsummary>Retrieves information about a connection.</fsummary> + <desc> + <p>Retrieves information about a connection. The list <c>Keys</c> defines which information that + is returned.</p> + </desc> + </func> +<!-- DEAMON/1,2,3 --> + <func> + <name>daemon(Port | TcpSocket) -> Result</name> + <name>daemon(Port | TcpSocket, Options) -> Result</name> + <name>daemon(HostAddress, Port, Options) -> Result</name> + <fsummary>Starts a server listening for SSH connections.</fsummary> + <type> + <v>Port = integer()</v> + <v>TcpSocket = <seealso marker="#type-open_socket">open_socket()</seealso></v> + <v>Options = <seealso marker="#type-daemon_options">daemon_options()</seealso></v> + <v>HostAddress = <seealso marker="#type-host">host()</seealso> | any</v> + <v>Result = {ok, <seealso marker="#type-daemon_ref">daemon_ref()</seealso>} | {error, atom()}</v> + </type> + <desc> + <p>Starts a server listening for SSH connections on the given 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>As an alternative, an already open TCP socket could be passed to the function in <c>TcpSocket</c>. + The SSH initiation and negotiation will be initiated on that one when an SSH starts at the other end + of the TCP socket. + </p> + <p>For a description of the options, see <seealso marker="#type-daemon_options">Daemon Options</seealso>. + </p> + <p>Please note that by historical reasons both the <c>HostAddress</c> argument and the + <seealso marker="kernel:gen_tcp#type-connect_option">gen_tcp connect_option() <c>{ip,Address}</c></seealso> + 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 the atom <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 the atom <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> + </desc> + </func> + +<!-- DAEMON_INFO/1 --> + <func> + <name name="daemon_info" arity="1"/> + <fsummary>Get info about a daemon</fsummary> + <desc> + <p>Returns a key-value list with information about the daemon.</p> + </desc> + </func> + + +<!-- DEFAULT_ALGORITHMS/0 --> <func> - <name>shell(Host) -> </name> - <name>shell(Host, Option) -> </name> - <name>shell(Host, Port, Option) -> _</name> - <fsummary> </fsummary> + <name name="default_algorithms" arity="0"/> + <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.</p> + <p>See the <seealso marker="configure_algos#example_default_algorithms">User's Guide</seealso> for + an example.</p> + </desc> + </func> + +<!-- SHELL/1,2,3 --> + <func> + <name>shell(Host | TcpSocket) -> Result </name> + <name>shell(Host | TcpSocket, Options) -> Result </name> + <name>shell(Host, Port, Options) -> Result </name> + <fsummary>Starts an interactive shell on a remote SSH server.</fsummary> <type> - <v> Host = string()</v> - <v> Port = integer()</v> - <v> Options - see ssh:connect/3</v> + <v>Host = <seealso marker="#type-host">host()</seealso></v> + <v>TcpSocket = <seealso marker="#type-open_socket">open_socket()</seealso></v> + <v>Port = <seealso marker="kernel:inet#type-port_number">inet:port_number()</seealso></v> + <v>Options = <seealso marker="#type-client_options">client_options()</seealso></v> + <v>Result = ok | {error, Reason::term()}</v> </type> <desc> - <p>Starts an interactive shell via 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. + <p>Connects to an SSH server at <c>Host</c> and <c>Port</c> (defaults to 22) and starts an + interactive shell on that remote host. + </p> + <p>As an alternative, an already open TCP socket could be passed to the function in <c>TcpSocket</c>. + The SSH initiation and negotiation will be initiated on that one and finaly a shell will be started + on the host at the other end of the TCP socket. + </p> + <p>For a description of the options, see <seealso marker="#type-client_options">Client Options</seealso>.</p> + <p>The function waits for user input, and does not return until the remote shell is ended (that is, exit from the shell). </p> </desc> </func> <func> - <name>start() -> </name> - <name>start(Type) -> ok | {error, Reason}</name> - <fsummary>Starts the SSH application. </fsummary> - <type> - <v>Type = permanent | transient | temporary</v> - <v>Reason = term() </v> - </type> + <name name="start" arity="0"/> + <name name="start" arity="1"/> + <fsummary>Starts the SSH application.</fsummary> <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> - <type> - <v>Reason = term()</v> - </type> + <name name="stop" arity="0"/> + <fsummary>Stops the <c>ssh</c> application.</fsummary> <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> <func> - <name>stop_daemon(DaemonRef) -> </name> - <name>stop_daemon(Address, Port) -> ok </name> - <fsummary>Stops the listener and all connections started by - the listener.</fsummary> - <type> - <v>DaemonRef = ssh_daemon_ref()</v> - <v>Address = ip_address()</v> - <v>Port = integer()</v> - </type> + <name name="stop_daemon" arity="1"/> + <name name="stop_daemon" arity="2"/> + <name name="stop_daemon" arity="3"/> + <fsummary>Stops the listener and all connections started by the listener.</fsummary> <desc> - <p>Stops the listener and all connections started by - the listener.</p> + <p>Stops the listener and all connections started by the listener.</p> </desc> </func> <func> - <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> - <type> - <v>DaemonRef = ssh_daemon_ref()</v> - <v>Address = ip_address()</v> - <v>Port = integer()</v> - </type> + <name name="stop_listener" arity="1"/> + <name name="stop_listener" arity="2"/> + <name name="stop_listener" arity="3"/> + <fsummary>Stops the listener, but leaves existing connections started by the listener operational.</fsummary> <desc> - <p>Stops the listener, but leaves existing connections started - by the listener up and running.</p> + <p>Stops the listener, but leaves existing connections started 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..e80bb1853d 100644 --- a/lib/ssh/doc/src/ssh_app.xml +++ b/lib/ssh/doc/src/ssh_app.xml @@ -4,97 +4,383 @@ <appref> <header> <copyright> - <year>2012</year><year>2013</year> + <year>2012</year><year>2018</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 options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + and + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + 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 (in the default order):</p> + <marker id="supported_algos"></marker> + <taglist> + <tag>Key exchange algorithms</tag> + <item> + <list type="bulleted"> + <item>ecdh-sha2-nistp384</item> + <item>ecdh-sha2-nistp521</item> + <item>ecdh-sha2-nistp256</item> + <item>diffie-hellman-group-exchange-sha256</item> + <item>diffie-hellman-group16-sha512</item> + <item>diffie-hellman-group18-sha512</item> + <item>diffie-hellman-group14-sha256</item> + <item>curve25519-sha256</item> + <item>[email protected]</item> + <item>curve448-sha512</item> + <item>diffie-hellman-group14-sha1</item> + <item>diffie-hellman-group-exchange-sha1</item> + <item>(diffie-hellman-group1-sha1, retired: It can be enabled with the + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + options)</item> + </list> + </item> + + <tag>Public key algorithms</tag> + <item> + <list type="bulleted"> + <item>ecdsa-sha2-nistp384</item> + <item>ecdsa-sha2-nistp521</item> + <item>ecdsa-sha2-nistp256</item> + <item>ssh-rsa</item> + <item>rsa-sha2-256</item> + <item>rsa-sha2-512</item> + <item>ssh-dss</item> + </list> + </item> + + <tag>MAC algorithms</tag> + <item> + <list type="bulleted"> + <item>hmac-sha2-256</item> + <item>hmac-sha2-512</item> + <item>hmac-sha1</item> + </list> + </item> + + <tag>Encryption algorithms (ciphers)</tag> + <item> + <list type="bulleted"> + <item>[email protected]</item> + <item>[email protected]</item> + <item>aes256-ctr</item> + <item>aes192-ctr</item> + <item>[email protected]</item> + <item>aes128-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 + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso> + options.</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 options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. </p> - </section> + <warning> + <p> + If the client or the server is not Erlang/OTP, it is the users responsibility to check that + other implementation has the same interpretation of AEAD_AES_*_GCM as the Erlang/OTP SSH before + enabling them. The aes*[email protected] variants are always safe to use since they lack the + ambiguity. + </p> + </warning> + <p>The second paragraph in section 5.1 is resolved as:</p> + <list type="ordered"> + <item>If the negotiated cipher is AEAD_AES_128_GCM, the mac algorithm is set to AEAD_AES_128_GCM.</item> + <item>If the negotiated cipher is AEAD_AES_256_GCM, the mac algorithm is set to AEAD_AES_256_GCM.</item> + <item>If the mac algorithm is AEAD_AES_128_GCM, the cipher is set to AEAD_AES_128_GCM.</item> + <item>If the mac algorithm is AEAD_AES_256_GCM, the cipher is set to AEAD_AES_256_GCM.</item> + </list> + <p>The first rule that matches when read in order from the top is applied</p> + </item> + + <item><url href="https://tools.ietf.org/html/rfc5656">RFC 5656</url>, Elliptic Curve Algorithm Integration in + the Secure Shell Transport Layer. + <p>Except</p> + <list type="bulleted"> + <item>5. ECMQV Key Exchange</item> + <item>6.4. ECMQV Key Exchange and Verification Method Name</item> + <item>7.2. ECMQV Message Numbers</item> + <item>10.2. Recommended Curves</item> + </list> + <p/> + </item> + + <item><url href="https://tools.ietf.org/html/rfc6668">RFC 6668</url>, SHA-2 Data Integrity Verification for + the Secure Shell (SSH) Transport Layer Protocol + <p>Comment: Defines hmac-sha2-256 and hmac-sha2-512 + </p> + </item> + + <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 options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. + </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 options + <seealso marker="ssh:ssh#type-preferred_algorithms_common_option">preferred_algorithms</seealso> + or + <seealso marker="ssh:ssh#type-modify_algorithms_common_option">modify_algorithms</seealso>. + They will be disabled by default when the draft is turned into an RFC.</item> + </list> + <p/> + </item> + + <item><url href="https://tools.ietf.org/html/rfc8332">RFC 8332</url>, Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol. + </item> + + <item><marker id="supported-ext-info"/> + <url href="https://tools.ietf.org/html/rfc8308">RFC 8308</url>, Extension Negotiation in the Secure Shell (SSH) Protocol. + <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> + + <item> + <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves">Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448 (work in progress)</url> + </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 deleted file mode 100644 index a52a6a115e..0000000000 --- a/lib/ssh/doc/src/ssh_channel.xml +++ /dev/null @@ -1,422 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> - -<erlref> - <header> - <copyright> - <year>2009</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. - - The Initial Developer of the Original Code is Ericsson AB. - </legalnotice> - <title>ssh_channel</title> - </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 - 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 - 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. - </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> - </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 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> - </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> - <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> - - </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 = - "#Module:handle_call-3">Module:handle_call/3</seealso> - to handle the message. If the channel process does not exist - <c>{error, closed}</c> is returned. - </p> - </desc> - </func> - - <func> - <name>cast(ChannelRef, Msg) -> ok </name> - <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> - </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 - <seealso marker = "#Module:handle_cast-2">Module:handle_cast/2</seealso> - to handle the message. - </p> - </desc> - </func> - - <func> - <name>enter_loop(State) -> _ </name> - <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> - </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> - </desc> - </func> - - <func> - <name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name> - <fsummary> Initiates a ssh_channel process.</fsummary> - <type> - <v>Options = [{Option, Value}]</v> - <v>State = term()</v> - <v>Timeout = timeout() </v> - <v>Reason = term() </v> - </type> - <desc> - <p> - The following options must be present: - </p> - <taglist> - <tag><c><![CDATA[{channel_cb, atom()}]]></c></tag> - <item>The module that implements the channel behaviour.</item> - - <tag><c><![CDATA[{init_args(), list()}]]></c></tag> - <item> The list of arguments to the callback module's - init function.</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> - - <tag><c><![CDATA[{channel_id, channel_id()}]]></c></tag> - <item> Id of the SSH channel.</item> - - </taglist> - - <note><p>This function is normally not called by the - user. The user only needs to call if for some reason 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> - </note> - </desc> - </func> - - <func> - <name>reply(Client, Reply) -> _</name> - <fsummary>Send a reply to a client.</fsummary> - <type> - <v>Client - opaque to the user, see explanation below</v> - <v>Reply = term()</v> - </type> - <desc> - <p>This function can be used by a channel to explicitly 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> - </desc> - </func> - - <func> - <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> - <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>ChannelCb = atom()</v> - <d> The 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> - <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> - </desc> - </func> - - </funcs> - - <section> - <marker id="cb_timeouts"></marker> - <title> CALLBACK TIMEOUTS</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> - </section> - - <funcs> - <func> - <name>Module:code_change(OldVsn, State, Extra) -> {ok, - NewState}</name> - <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 - in the case of a downgrade, <c>OldVsn</c> is - <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> - attribute(s) of the old version of the callback module - <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> - <v>Extra = term()</v> - <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>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> - - <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> - </note> - - </desc> - </func> - - <func> - <name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} | - {stop, Reason}</name> - <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> - </type> - <desc> - <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> - </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> - <type> - <v>Msg = term()</v> - <v>From = opaque to the user should be used as argument to - ssh_channel:reply/2</v> - <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>NewState = term()</v> - <v>Reason = term()</v> - </type> - <desc> - <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> - </desc> - </func> - - <func> - <name>Module:handle_cast(Msg, State) -> Result</name> - <fsummary> Handles messages sent by calling - <c>ssh_channel:cact/2</c></fsummary> - <type> - <v>Msg = term()</v> - <v>State = term()</v> - <v>Result = {noreply, NewState} | {noreply, NewState, timeout()} - | {stop, Reason, NewState}</v> - <v>NewState = term() </v> - <v>Reason = term()</v> - </type> - <desc> - <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> - </desc> - </func> - - <func> - <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> - <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 - 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> - - <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 - marker="#init-1">ssh_channel:init/1</seealso> function - 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> - </taglist> - </desc> - </func> - - <func> - <name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, - ChannelId, State}</name> - <fsummary> Handles ssh connection protocol messages. </fsummary> - <type> - <v>Msg = <seealso marker="ssh_connection"> ssh_connection:event() </seealso> </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> - - <p> The following message is completely taken care of by the - SSH channel 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> - </taglist> - </desc> - </func> - - <func> - <name>Module:terminate(Reason, State) -> _</name> - <fsummary> </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 - 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 - up. When it returns, the channel process terminates with - reason <c>Reason</c>. The return value is ignored. - </p> - </desc> - </func> - - </funcs> - -</erlref> diff --git a/lib/ssh/doc/src/ssh_client_channel.xml b/lib/ssh/doc/src/ssh_client_channel.xml new file mode 100644 index 0000000000..9be4007c68 --- /dev/null +++ b/lib/ssh/doc/src/ssh_client_channel.xml @@ -0,0 +1,440 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2009</year> + <year>2018</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. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + <title>ssh_client_channel</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>ssh_client_channel</module> + <modulesummary>-behaviour(ssh_client_channel). (Replaces ssh_channel) + </modulesummary> + <description> + <note> + <p>This module replaces ssh_channel.</p> + <p>The old module is still available for compatibility, but should not be used for new programs. + The old module will not be maintained except for some error corrections + </p> + </note> + <p>SSH services (clients and servers) are implemented as channels + 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 for clients, 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 <c>ssh</c> applications supervisor tree. + </p> + + <note><p>When implementing a <c>ssh</c> subsystem for daemons, use + <seealso marker="ssh_server_channel">-behaviour(ssh_server_channel)</seealso> (Replaces ssh_daemon_channel) + instead. + </p> + </note> + + <dont> + <p>Functions in this module are not supposed to be called outside a module implementing this + behaviour! + </p> + </dont> + + </description> + + <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> + <type> + <v>ChannelRef = pid() </v> + <d>As returned by <seealso marker = "#start_link-4">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 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, + <c>{error, closed}</c> is returned. + </p> + </desc> + </func> + + <func> + <name>cast(ChannelRef, Msg) -> ok </name> + <fsummary>Sends an asynchronous message to the channel + ChannelRef and returns ok.</fsummary> + <type> + <v>ChannelRef = pid()</v> + <d>As returned by <seealso marker = "#start_link-4">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 calls + <seealso marker = "#Module:handle_cast-2">Module:handle_cast/2</seealso> + to handle the message. + </p> + </desc> + </func> + + <func> + <name>enter_loop(State) -> _ </name> + <fsummary>Makes an existing process an ssh_client_channel (replaces ssh_channel) process.</fsummary> + <type> + <v>State = term()</v> + <d>as returned by <seealso marker = "#init-1">init/1</seealso></d> + </type> + <desc> + <p>Makes an existing process an <c>ssh_client_channel</c> (replaces ssh_channel) + process. Does not return, instead the calling process + enters the <c>ssh_client_channel</c> (replaces ssh_channel) process receive loop and become an + <c>ssh_client_channel</c> process. 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">init/1</seealso>. + </p> + </desc> + </func> + + <func> + <name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name> + <fsummary>Initiates an <c>ssh_client_channel</c> process.</fsummary> + <type> + <v>Options = [{Option, Value}]</v> + <v>State = term()</v> + <v>Timeout = timeout()</v> + <v>Reason = term()</v> + </type> + <desc> + <p> + The following options must be present: + </p> + <taglist> + <tag><c>{channel_cb, atom()}</c></tag> + <item><p>The module that implements the channel behaviour.</p></item> + + <tag><c>{init_args(), list()}</c></tag> + <item><p>The list of arguments to the <c>init</c> function of the callback module.</p></item> + + <tag><c>{cm, ssh:connection_ref()}</c></tag> + <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>{channel_id, ssh:channel_id()}</c></tag> + <item><p>Id of the <c>ssh</c> channel as returned by + <seealso marker="ssh_connection#session_channel/2">ssh_connection:session_channel/2,4</seealso>. + </p></item> + + </taglist> + + <note><p>This function is normally not called by 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>start/4</c> or + <c>start_link/4</c>.</p> + </note> + </desc> + </func> + + <func> + <name>reply(Client, Reply) -> _</name> + <fsummary>Sends a reply to a client.</fsummary> + <type> + <v>Client = opaque()</v> + <v>Reply = term()</v> + </type> + <desc> + <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 is given back to the client as the return value of + <seealso marker="#call-2">call/[2,3].</seealso></p> + </desc> + </func> + + <func> + <name>start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name> + <name>start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> + {ok, ChannelRef} | {error, Reason}</name> + <fsummary>Starts a process that handles an SSH channel.</fsummary> + <type> + <v>SshConnection = ssh:connection_ref()</v> + <d>As returned by <seealso marker="ssh#connect-3">ssh:connect/3</seealso></d> + + <v>ChannelId = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></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>Name of the module implementing the service-specific parts + of the channel.</d> + + <v>CbInitArgs = [term()]</v> + <d>Argument list for the <c>init</c> function in the callback module.</d> + + <v>ChannelRef = pid()</v> + </type> + <desc> + <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> + + </funcs> + + <section> + <title>Callback Functions</title> + <p> + The following functions are to be exported from a + <c>ssh_client_channel</c> callback module. + </p> + <marker id="cb_timeouts"></marker> + <section> + <title>Callback timeouts</title> + <p>The timeout 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> + </section> + + <funcs> + <func> + <name>Module:code_change(OldVsn, State, Extra) -> {ok, + NewState}</name> + <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 + in the case of a downgrade, <c>OldVsn</c> is + <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> + attribute(s) of the old version of the callback module + <c>Module</c>. If no such attribute is defined, the version is + the checksum of the BEAM file.</d> + <v>State = term()</v> + <d>Internal state of the channel.</d> + <v>Extra = term()</v> + <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>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 <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> + </func> + + <func> + <name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} | + {stop, Reason}</name> + <fsummary>Makes necessary initializations and returns the + initial channel state if the initializations succeed.</fsummary> + <type> + <v>Args = term()</v> + <d>Last argument to <c>start_link/4</c>.</d> + <v>State = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Makes necessary initializations and returns the initial channel + state if the initializations succeed. + </p> + <p>For more detailed information on time-outs, see Section + <seealso marker="#cb_timeouts">Callback timeouts</seealso>. </p> + </desc> + </func> + + <func> + <name>Module:handle_call(Msg, From, State) -> Result</name> + <fsummary>Handles messages sent by calling + <c>call/[2,3]</c>.</fsummary> + <type> + <v>Msg = term()</v> + <v>From = opaque()</v> + <d>Is to be used as argument to + <seealso marker="#reply-2">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()</v> + <d>Will be the return value of <seealso marker="#call-2">call/[2,3]</seealso></d> + <v>NewState = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Handles messages sent by calling + <seealso marker="#call-2">call/[2,3]</seealso> + </p> + <p>For more detailed information on time-outs,, see Section + <seealso marker="#cb_timeouts">Callback timeouts</seealso>.</p> + </desc> + </func> + + <func> + <name>Module:handle_cast(Msg, State) -> Result</name> + <fsummary>Handles messages sent by calling + <c>cast/2</c>.</fsummary> + <type> + <v>Msg = term()</v> + <v>State = term()</v> + <v>Result = {noreply, NewState} | {noreply, NewState, timeout()} + | {stop, Reason, NewState}</v> + <v>NewState = term() </v> + <v>Reason = term()</v> + </type> + <desc> + <p>Handles messages sent by calling + <c>cast/2</c>. + </p> + <p>For more detailed information on time-outs, see Section + <seealso marker="#cb_timeouts">Callback timeouts</seealso>.</p> + </desc> + </func> + + <func> + <name>Module:handle_msg(Msg, State) -> {ok, State} | + {stop, ChannelId, State}</name> + + <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 = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v> + <v>State = term() </v> + </type> + <desc> + <p>Handles other messages than SSH Connection Protocol, call, or + cast messages sent to the channel. + </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>{ssh_channel_up, ssh:channel_id(), ssh:connection_ref()}</c></tag> + <item><p>This is the first message that the channel receives. + It is sent just before the <seealso + marker="#init-1">init/1</seealso> function + 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, ignore it by + immediately returning <c>{ok, State}</c>. + </p></item> + </taglist> + </desc> + </func> + + <func> + <name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, + ChannelId, State}</name> + <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary> + <type> + <v>Msg = ssh_connection:event()</v> + <v>ChannelId = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v> + <v>State = term()</v> + </type> + <desc> + <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 taken care of by the + <c>ssh_client_channel</c> behavior.</p> + + <taglist> + <tag><c>{closed, ssh:channel_id()}</c></tag> + <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>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 + marker="ssh_connection#close-2"> ssh_connection:close/2 + </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> + </desc> + </func> + + </funcs> + +</erlref> diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml index f3d05a8980..bc77756147 100644 --- a/lib/ssh/doc/src/ssh_client_key_api.xml +++ b/lib/ssh/doc/src/ssh_client_key_api.xml @@ -5,120 +5,145 @@ <header> <copyright> <year>2012</year> - <year>2013</year> + <year>2018</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> + <!-- 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. 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> - - </section> + <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 --> + + <datatypes> + <datatype> + <name name="client_key_cb_options"/> + <desc> + <p>Options provided to <seealso marker="ssh#connect-3">ssh:connect/[3,4]</seealso>. + </p> + <p>The option list given in the + <seealso marker="ssh#type-key_cb_common_option"><c>key_cb</c></seealso> + option is available with the key <c>key_cb_private</c>. + </p> + </desc> + </datatype> + </datatypes> <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> + <name>Module:add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name> + <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> + <v>HostNames = string()</v> + <d>Description of the host that owns the <c>PublicHostKey</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>PublicHostKey = <seealso marker="public_key:public_key#type-public_key">public_key:public_key()</seealso></v> + <d>Of ECDSA keys, only the 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 = <seealso marker="#type-client_key_cb_options">client_key_cb_options()</seealso></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> + <v>Key = <seealso marker="public_key:public_key#type-public_key">public_key:public_key()</seealso></v> + <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> + <v>Algorithm = <seealso marker="ssh#type-pubkey_alg">ssh:pubkey_alg()</seealso></v> + <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 = <seealso marker="#type-client_key_cb_options">client_key_cb_options()</seealso></v> - <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> + <v>Algorithm = <seealso marker="ssh#type-pubkey_alg">ssh:pubkey_alg()</seealso></v> + <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 = <seealso marker="#type-client_key_cb_options">client_key_cb_options()</seealso></v> - <v> PrivateKey = private_key()</v> - <d> The private key of the user matching the <c>Algorithm</c></d> + <v>PrivateKey = <seealso marker="public_key:public_key#type-private_key">public_key:private_key()</seealso></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..8e1cf156a8 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>2018</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, connection_ref(), ssh_event_msg()}]]></c>. + If the <seealso marker="ssh_client_channel">ssh_client_channel</seealso> behavior is used to + implement the channel process, these messages are handled by + <seealso marker="ssh_client_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><b>data_events()</b></tag> + <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>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>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, 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><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[{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> + <tag><c><![CDATA[{data, 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, channel_id()}]]></c></tag> + <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 + <tag><c><![CDATA[{signal, channel_id(), ssh_signal()}]]></c></tag> + <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, 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, 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> + <tag><c><![CDATA[{closed, channel_id()}]]></c></tag> + <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_client_channel">ssh_client_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[{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 + <tag><c><![CDATA[{env, 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, channel_id(), + 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, 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> + <tag><c><![CDATA[{exec, channel_id(), + 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 = connection_ref()</v> + <v>ChannelId = 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 - the callback <seealso marker="ssh_channel#Module:handle_ssh_msg-2"> - handle_ssh_msg/2 </seealso> has returned after processing channel data</p> </note> + <note><p>Channels implemented with the <seealso marker="ssh_client_channel"> ssh_client_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_client_channel#Module:handle_ssh_msg-2"> + 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 = connection_ref()</v> + <v>ChannelId = 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_client_channel</c> + behavior when the channel is terminated, see <seealso + marker="ssh_client_channel"> ssh_client_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 = connection_ref()</v> + <v>ChannelId = 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, connection_ref(), + {data, 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> + <tag><c>0 or 1 x {ssh_cm, connection_ref(), {eof, channel_id()}}</c></tag> + <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> + connection_ref(), {exit_signal, + 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> - - <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> + <tag><c>0 or 1 x {ssh_cm, connection_ref(), {exit_status, + 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, connection_ref(), + {closed, channel_id()}}</c></tag> + <item><p>Indicates that the <c>ssh_client_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 = connection_ref() </v> + <v>ChannelId = 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 = connection_ref()</v> + <v>ChannelId = 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 = connection_ref()</v> + <v>WantReply = boolean()</v> + <v>Status = ssh_request_status()</v> + <v>ChannelId = 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,107 @@ <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 = connection_ref()</v> + <v>ChannelId = 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 = connection_ref()</v> + <v>ChannelId = 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> + MaxPacketSize, Timeout) -> {ok, channel_id()} | {error, reason()}</name> + <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 = 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 = connection_ref()</v> + <v>ChannelId = 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>shell(ConnectionRef, ChannelId) -> ok | failure | {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 = connection_ref()</v> + <v>ChannelId = 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>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> + <p>Note: the return value is <c>ok</c> instead of <c>success</c> unlike in other + functions in this module. This is a fault that was introduced so long ago that + any change would break a large number of existing software. </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 = connection_ref()</v> + <v>ChannelId = 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..0d99a96997 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>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -87,8 +87,10 @@ connection, and all channels are flow-controlled. Typically an SSH client will open a channel, send data/commands, receive data/"control information" and when it is done close the - channel. The <seealso - marker="ssh_channel">ssh_channel</seealso> behaviour makes it easy to + channel. The + <seealso marker="ssh_client_channel">ssh_client_channel</seealso> / + <seealso marker="ssh_server_channel">ssh_server_channel</seealso> (Replaces ssh_daemon_channel) + behaviours makes it easy to write your own SSH client/server processes that use flow control. It handles generic parts of SSH channel management and lets you focus on the application logic. @@ -138,8 +140,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_channel.xml b/lib/ssh/doc/src/ssh_server_channel.xml new file mode 100644 index 0000000000..31ba9a3231 --- /dev/null +++ b/lib/ssh/doc/src/ssh_server_channel.xml @@ -0,0 +1,176 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2009</year> + <year>2018</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. + + The Initial Developer of the Original Code is Ericsson AB. + </legalnotice> + <title>ssh_server_channel</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>ssh_server_channel</module> + <modulesummary>-behaviour(ssh_server_channel). (Replaces ssh_daemon_channel) + </modulesummary> + <description> + <note> + <p>This module replaces ssh_daemon_channel.</p> + <p>The old module is still available for compatibility, but should not be used for new programs. + The old module will not be maintained except for some error corrections + </p> + </note> + + <p>SSH services (clients and servers) are implemented as channels + 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 for daemons, 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 <c>ssh</c> applications supervisor tree. + </p> + + <note><p>When implementing a client subsystem handler, use + <seealso marker="ssh_client_channel">-behaviour(ssh_client_channel)</seealso> instead. + </p> + </note> + + </description> + + <section> + <title>Callback Functions</title> + <p> + The following functions are to be exported from a + <c>ssh_server_channel</c> callback module. + </p> + </section> + + <funcs> + <func> + <name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} | + {stop, Reason}</name> + <fsummary>Makes necessary initializations and returns the + initial channel state if the initializations succeed.</fsummary> + <type> + <v>Args = term()</v> + <d>Last argument to <c>start_link/4</c>.</d> + <v>State = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Makes necessary initializations and returns the initial channel + state if the initializations succeed. + </p> + <p>The time-out values that can be returned + 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> + </desc> + </func> + + <func> + <name>Module:handle_msg(Msg, State) -> {ok, State} | + {stop, ChannelId, State}</name> + + <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 = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v> + <v>State = term() </v> + </type> + <desc> + <p>Handles other messages than SSH Connection Protocol, call, or + cast messages sent to the channel. + </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>{ssh_channel_up, ssh:channel_id(), ssh:connection_ref()}</c></tag> + <item><p>This is the first message that the channel receives. + 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, ignore it by + immediately returning <c>{ok, State}</c>. + </p></item> + </taglist> + </desc> + </func> + + <func> + <name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, + ChannelId, State}</name> + <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary> + <type> + <v>Msg = ssh_connection:event()</v> + <v>ChannelId = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v> + <v>State = term()</v> + </type> + <desc> + <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 taken care of by the + <c>ssh_server_channel</c> behavior.</p> + + <taglist> + <tag><c>{closed, ssh:channel_id()}</c></tag> + <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>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 + marker="ssh_connection#close-2"> ssh_connection:close/2 + </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> + </desc> + </func> + + </funcs> + +</erlref> diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml index f7133e4ba5..e2a31bd5f5 100644 --- a/lib/ssh/doc/src/ssh_server_key_api.xml +++ b/lib/ssh/doc/src/ssh_server_key_api.xml @@ -5,86 +5,127 @@ <header> <copyright> <year>2012</year> - <year>2013</year> + <year>2018</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> + <!-- 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. 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> - </section> + <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 --> + + <datatypes> + <datatype> + <name name="daemon_key_cb_options"/> + <desc> + <p>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/2,3</seealso>. + </p> + <p>The option list given in the + <seealso marker="ssh#type-key_cb_common_option"><c>key_cb</c></seealso> + option is available with the key <c>key_cb_private</c>. + </p> + </desc> + </datatype> + </datatypes> <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> + <v>Algorithm = <seealso marker="ssh#type-pubkey_alg">ssh:pubkey_alg()</seealso></v> + <d>Host key algorithm.</d> + + <v>DaemonOptions = <seealso marker="#type-daemon_key_cb_options">daemon_key_cb_options()</seealso></v> + + <v>PrivateKey = <seealso marker="public_key:public_key#type-private_key">public_key:private_key()</seealso> + | <seealso marker="crypto:crypto#type-engine_key_ref">crypto:engine_key_ref()</seealso> + </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> + <name>Module:is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name> + <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>PublicUserKey = <seealso marker="public_key:public_key#type-public_key">public_key:public_key()</seealso></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 = <seealso marker="#type-daemon_key_cb_options">daemon_key_cb_options()</seealso></v> + + <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..ea55126cb3 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>2018</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>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>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>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_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 = 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..3b34150e98 100644 --- a/lib/ssh/doc/src/ssh_sftpd.xml +++ b/lib/ssh/doc/src/ssh_sftpd.xml @@ -4,85 +4,91 @@ <erlref> <header> <copyright> - <year>2005</year><year>2013</year> + <year>2005</year><year>2018</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 + <seealso marker="ssh_server_channel">ssh_server_channel</seealso> (replaces ssh_daemon_channel) behaviour.</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..38ffa48cde 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>2018</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..80662e9a70 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>2018</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,82 @@ </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> + <marker id="usersguide_creating_a_subsystem"/> + <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_server_channel). % replaces ssh_daemon_channel -record(state, { n, id, @@ -267,14 +356,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 +384,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_client_channel">ssh_client_channel(3)</seealso> (replaces ssh_channel(3)).</p> </section> |