aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/doc
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2019-02-06 19:10:26 +0100
committerSverker Eriksson <[email protected]>2019-02-06 19:10:26 +0100
commit98cfd6016f8b40fc97e03b31177d14318349040f (patch)
treec0fcdd768071c36bfbcbf186d369d9ca14c47421 /lib/ssh/doc
parente2ca71b6e7172b320b5b171359d53a161383fb19 (diff)
parent3825199794da28d79b21052a2e69e2335921d55e (diff)
downloadotp-98cfd6016f8b40fc97e03b31177d14318349040f.tar.gz
otp-98cfd6016f8b40fc97e03b31177d14318349040f.tar.bz2
otp-98cfd6016f8b40fc97e03b31177d14318349040f.zip
Merge tag 'OTP-21.2' into sverker/map-from-ks-vs-bug
Diffstat (limited to 'lib/ssh/doc')
-rw-r--r--lib/ssh/doc/specs/.gitignore1
-rw-r--r--lib/ssh/doc/src/Makefile44
-rw-r--r--lib/ssh/doc/src/configure_algos.xml429
-rw-r--r--lib/ssh/doc/src/fascicules.xml18
-rw-r--r--lib/ssh/doc/src/introduction.xml6
-rw-r--r--lib/ssh/doc/src/notes.xml1173
-rw-r--r--lib/ssh/doc/src/part_notes.xml38
-rw-r--r--lib/ssh/doc/src/ref_man.xml6
-rw-r--r--lib/ssh/doc/src/specs.xml14
-rw-r--r--lib/ssh/doc/src/ssh.xml1551
-rw-r--r--lib/ssh/doc/src/ssh_app.xml118
-rw-r--r--lib/ssh/doc/src/ssh_client_channel.xml (renamed from lib/ssh/doc/src/ssh_channel.xml)165
-rw-r--r--lib/ssh/doc/src/ssh_client_key_api.xml70
-rw-r--r--lib/ssh/doc/src/ssh_connection.xml118
-rw-r--r--lib/ssh/doc/src/ssh_file.xml285
-rw-r--r--lib/ssh/doc/src/ssh_protocol.xml10
-rw-r--r--lib/ssh/doc/src/ssh_server_channel.xml176
-rw-r--r--lib/ssh/doc/src/ssh_server_key_api.xml63
-rw-r--r--lib/ssh/doc/src/ssh_sftp.xml32
-rw-r--r--lib/ssh/doc/src/ssh_sftpd.xml5
-rw-r--r--lib/ssh/doc/src/terminology.xml185
-rw-r--r--lib/ssh/doc/src/usersguide.xml4
-rw-r--r--lib/ssh/doc/src/using_ssh.xml18
23 files changed, 3661 insertions, 868 deletions
diff --git a/lib/ssh/doc/specs/.gitignore b/lib/ssh/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/lib/ssh/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index a759854da4..4e32dd9976 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2016. All Rights Reserved.
+# Copyright Ericsson AB 2004-2018. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -38,27 +38,32 @@ 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_file.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 \
+ terminology.xml \
+ configure_algos.xml
BOOK_FILES = book.xml
XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES)\
- $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
IMAGE_FILES = SSH_protocols.png
@@ -83,11 +88,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
@@ -108,19 +120,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/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 ca84528f3d..8444daf0cc 100644
--- a/lib/ssh/doc/src/introduction.xml
+++ b/lib/ssh/doc/src/introduction.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2012</year>
- <year>2016</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -145,7 +145,7 @@
data that can be sent to the channel peer without adjusting the
window. Typically, an SSH client opens a channel, sends data (commands),
receives data (control information), and then closes the channel.
- The <seealso marker="ssh_channel">ssh_channel</seealso> behaviour
+ 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.
@@ -195,8 +195,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/notes.xml b/lib/ssh/doc/src/notes.xml
index b990c18e9a..177784384e 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -30,6 +30,1074 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.7.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Incompatibility with newer OpenSSH fixed. Previously
+ versions 7.8 and later could cause Erlang SSH to exit.</p>
+ <p>
+ Own Id: OTP-15413</p>
+ </item>
+ <item>
+ <p>
+ The '<c>exec</c>' option for ssh daemons had wrong format
+ in the documentation.</p>
+ <p>
+ Own Id: OTP-15416</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added public key methods ssh-ed25519 and ssh-ed448.</p>
+ <p>
+ Requires OpenSSL 1.1.1 or higher as cryptolib under the
+ OTP application <c>crypto</c>.</p>
+ <p>
+ Own Id: OTP-15094 Aux Id: OTP-15419 </p>
+ </item>
+ <item>
+ <p>
+ The SSH property tests are now adapted to the PropEr
+ testing tool.</p>
+ <p>
+ Own Id: OTP-15312</p>
+ </item>
+ <item>
+ <p>
+ The term "user" was not documented in the SSH app. A new
+ chapter with terminology is added to the User's Manual
+ where the term "user" is defined.</p>
+ <p>
+ A reference manual page about the module <c>ssh_file</c>
+ is also added. This is the default callback module for
+ user's keys, host keys etc.</p>
+ <p>
+ Own Id: OTP-15314</p>
+ </item>
+ <item>
+ <p>
+ Host and user key checking is made more robust.</p>
+ <p>
+ Own Id: OTP-15424</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<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.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Incompatibility with newer OpenSSH fixed. Previously
+ versions 7.8 and later could cause Erlang SSH to exit.</p>
+ <p>
+ Own Id: OTP-15413</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.9.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ SFTP clients reported the error reason <c>""</c> if a
+ non-OTP sftp server was killed during a long file
+ transmission.</p>
+ <p>
+ Now the signal name (for example <c>"KILL"</c>) will be
+ the error reason if the server's reason is empty.</p>
+ <p>
+ The documentation also lacked type information about this
+ class of errors.</p>
+ <p>
+ Own Id: OTP-15148 Aux Id: ERIERL-194 </p>
+ </item>
+ <item>
+ <p>
+ Fix ssh_sftp decode error for sftp protocol version 4</p>
+ <p>
+ Own Id: OTP-15149 Aux Id: ERIERL-199 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Host key hash erroneously calculated for clients
+ following draft-00 of RFC 4419, for example PuTTY</p>
+ <p>
+ Own Id: OTP-15064</p>
+ </item>
+ <item>
+ <p>
+ Renegotiation could fail in some states</p>
+ <p>
+ Own Id: OTP-15066</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.8</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ An ssh_sftp server (running version 6) could fail if it
+ is told to remove a file which in fact is a directory.</p>
+ <p>
+ Own Id: OTP-15004</p>
+ </item>
+ <item>
+ <p>
+ Fix rare spurios shutdowns of ssh servers when receiveing
+ <c>{'EXIT',_,normal}</c> messages.</p>
+ <p>
+ Own Id: OTP-15018</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bad spec in ssh.hrl: <c>double_algs()</c>.</p>
+ <p>
+ Own Id: OTP-14990</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Remove a blocking risk when a channel is closed and an
+ operation is tried on that channel after at least a
+ second's time gap.</p>
+ <p>
+ Own Id: OTP-14939</p>
+ </item>
+ </list>
+ </section>
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Added ssh_compat_SUITE.</p>
+ <p>
+ This suite contains a number of interoperability tests
+ mainly with OpenSSH. The tests start docker containers
+ with different OpenSSH and OpenSSL/LibreSSLcryptolib
+ versions and performs a number of tests of supported
+ algorithms.</p>
+ <p>
+ All login methods and all user's public key types are
+ tested both for the client and the server.</p>
+ <p>
+ All algorithms for kex, cipher, host key, mac and
+ compressions are tested with a number of exec and sftp
+ tests, both for the client and the server.</p>
+ <p>
+ Own Id: OTP-14194 Aux Id: OTP-12487 </p>
+ </item>
+ <item>
+ <p>
+ Default exec is disabled when a user-defined shell is
+ enabled.</p>
+ <p>
+ Own Id: OTP-14881</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Adjusted supervisor timeouts</p>
+ <p>
+ Own Id: OTP-14907</p>
+ </item>
+ <item>
+ <p>
+ Remove ERROR messages for slow process exits</p>
+ <p>
+ Own Id: OTP-14930</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add option <c>save_accepted_host</c> to
+ <c>ssh:connection</c>. This option, if set to false,
+ inhibits saving host keys to e.g the file
+ <c>known_hosts</c>.</p>
+ <p>
+ Own Id: OTP-14935</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix problem with OpenSSH 7.2 (and later) clients that has
+ used sha1 instead of sha2 for rsa-sha-256/512 user's
+ public keys.</p>
+ <p>
+ Own Id: OTP-14827 Aux Id: ERL-531 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Passphrase option for ecdsa public keys was missing.</p>
+ <p>
+ Own Id: OTP-14602</p>
+ </item>
+ </list>
+ </section>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The host and user public key handling is hardened so that
+ a faulty plugin can't deliver a key of wrong type.</p>
+ <p>
+ Better checks in the server of the available hostkey's
+ types at start and at each accept.</p>
+ <p>
+ Better checks in the client of the available user public
+ key types at connect.</p>
+ <p>
+ Own Id: OTP-14676 Aux Id: ERIERL-52, OTP-14570 </p>
+ </item>
+ <item>
+ <p>
+ SSH can now fetch the host key from the private keys
+ stored in an Engine. See the crypto application for
+ details about Engines.</p>
+ <p>
+ Own Id: OTP-14757</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.2</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Trailing white space was removed at end of the
+ hello-string. This caused interoperability problems with
+ some other ssh-implementations (e.g OpenSSH 7.3p1 on
+ Solaris 11)</p>
+ <p>
+ Own Id: OTP-14763 Aux Id: ERIERL-74 </p>
+ </item>
+ <item>
+ <p>
+ Fixes that tcp connections that was immediately closed
+ (SYN, SYNACK, ACK, RST) by a client could be left in a
+ zombie state.</p>
+ <p>
+ Own Id: OTP-14778 Aux Id: ERIERL-104 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6.1</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed broken printout</p>
+ <p>
+ Own Id: OTP-14645</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Disable aes_gcm ciphers if peer is OpenSSH 6.2 which is
+ known to have trouble with them in some cases.</p>
+ <p>
+ Own Id: OTP-14638</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Enables the <c>ssh_io module</c> to also accept binary
+ values when reading standard_io instead of getting stuck
+ in the receive clause.</p>
+ <p>
+ Own Id: OTP-14506 Aux Id: PR1503 </p>
+ </item>
+ <item>
+ <p>
+ Previously, the file owner access permission in response
+ to ssh_sftp:read_file_info/2 function was always
+ <c>read_write</c>. With this fix, the actual value of
+ file owner access permission is added to the returning
+ record. That value is calculated from file mode value.</p>
+ <p>
+ Own Id: OTP-14550 Aux Id: PR1533 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ A new option <c>modify_algorithms</c> is implemented. It
+ enables specifying changes on the default algorithms
+ list. See the reference manual and the SSH User's Guide
+ chapter "Configuring algorithms in SSH".</p>
+ <p>
+ Own Id: OTP-14568</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ All unknown options are sent to the transport handler
+ regardless of type.</p>
+ <p>
+ Own Id: OTP-14541 Aux Id: EIRERL-63 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The internal handling of SSH options is re-written.</p>
+ <p>
+ Previously there were no checks if a client option was
+ given to a daemon or vice versa. This is corrected now.
+ If your code has e.g. a client-only option in a call to
+ start a daemon, the call will fail.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-12872</p>
+ </item>
+ <item>
+ <p>
+ Modernization of key exchange algorithms. See
+ draft-ietf-curdle-ssh-kex-sha2 for a discussion.</p>
+ <p>
+ Removed an outdated weak algorithm and added stronger
+ replacements to keep interoperability with other modern
+ ssh clients and servers. The default ordering of the
+ algorithms is also adjusted.</p>
+ <p>
+ Retired: The nowadays unsecure key-exchange
+ <c>diffie-hellman-group1-sha1</c> is not enabled by
+ default, but can be enabled with the option
+ <c>preferred-algorithms</c>.</p>
+ <p>
+ Added: The new stronger key-exchange
+ <c>diffie-hellman-group16-sha512</c>,
+ <c>diffie-hellman-group18-sha512</c> and
+ <c>diffie-hellman-group14-sha256</c> are added and
+ enabled by default.</p>
+ <p>
+ The questionable [RFC 6194] sha1-based algorithms
+ <c>diffie-hellman-group-exchange-sha1</c> and
+ <c>diffie-hellman-group14-sha1</c> are however still kept
+ enabled by default for compatibility with ancient clients
+ and servers that lack modern key-exchange alternatives.
+ When the draft-ietf-curdle-ssh-kex-sha2 becomes an rfc,
+ those sha1-based algorithms and
+ <c>diffie-hellman-group1-sha1</c> will be deprecated by
+ IETF. They might then be removed from the default list in
+ Erlang/OTP.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14110</p>
+ </item>
+ <item>
+ <p>
+ Modernized internal representation of sftp by use of
+ maps.</p>
+ <p>
+ Own Id: OTP-14117</p>
+ </item>
+ <item>
+ <p>
+ The Extension Negotiation Mechanism and the extension
+ <c>server-sig-algs</c> in
+ draft-ietf-curdle-ssh-ext-info-05 are implemented.</p>
+ <p>
+ The related draft-ietf-curdle-rsa-sha2-05 is implemented
+ and introduces the signature algorithms
+ <c>rsa-sha2-256</c> and <c>rsa-sha2-512</c>.</p>
+ <p>
+ Own Id: OTP-14193</p>
+ </item>
+ <item>
+ <p>
+ The 'timeout' and 'connect_timeout' handling in
+ ssh_sftp:start_channel documentation is clarified.</p>
+ <p>
+ Own Id: OTP-14216</p>
+ </item>
+ <item>
+ <p>
+ The functions <c>ssh:connect</c>, <c>ssh:shell</c> and
+ <c>ssh:start_channel</c> now accept an IP-tuple as Host
+ destination argument.</p>
+ <p>
+ Own Id: OTP-14243</p>
+ </item>
+ <item>
+ <p>
+ The function <c>ssh:daemon_info/1</c> now returns Host
+ and Profile as well as the Port info in the property
+ list.</p>
+ <p>
+ Own Id: OTP-14259</p>
+ </item>
+ <item>
+ <p>
+ Removed the option <c>public_key_alg</c> which was
+ deprecated in 18.2. Use <c>pref_public_key_algs</c>
+ instead.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14263</p>
+ </item>
+ <item>
+ <p>
+ The SSH application is refactored regarding daemon
+ starting. The resolution of contradicting <c>Host</c>
+ argument and <c>ip</c> option were not described. There
+ were also strange corner cases when the <c>'any'</c>
+ value was used in <c>Host</c> argument or <c>ip</c>
+ option. This is (hopefully) resolved now, but it may
+ cause incompatibilities for code using both <c>Host</c>
+ and the <c>ip</c> option. The value 'loopback' has been
+ added for a correct way of naming those addresses.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-14264</p>
+ </item>
+ <item>
+ <p>
+ The supervisor code is refactored. The naming of
+ listening IP-Port-Profile triples are slightly changed to
+ improve consistency in strange corner cases as resolved
+ by OTP-14264</p>
+ <p>
+ Own Id: OTP-14267 Aux Id: OTP-14266 </p>
+ </item>
+ <item>
+ <p>
+ The <c>idle_time</c> option can now be used in daemons.</p>
+ <p>
+ Own Id: OTP-14312</p>
+ </item>
+ <item>
+ <p>
+ Added test cases for IETF-CURDLE Extension Negotiation
+ (ext-info)</p>
+ <p>
+ Own Id: OTP-14361</p>
+ </item>
+ <item>
+ <p>
+ Testcases for IETF-CURDLE extension
+ <c>server-sig-algs</c> including <c>rsa-sha2-*</c></p>
+ <p>
+ Own Id: OTP-14362 Aux Id: OTP-14361 </p>
+ </item>
+ <item>
+ <p>
+ The option <c>auth_methods</c> can now also be used in
+ clients to select which authentication options that are
+ used and in which order.</p>
+ <p>
+ Own Id: OTP-14399</p>
+ </item>
+ <item>
+ <p>
+ Checks that a ECDSA public key (<c>ecdsa-sha2-nistp*</c>)
+ stored in a file has the correct size.</p>
+ <p>
+ Own Id: OTP-14410</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Ssh 4.4.2.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>
@@ -194,6 +1262,108 @@
</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>
@@ -2778,4 +3948,3 @@
</section>
</chapter>
-
diff --git a/lib/ssh/doc/src/part_notes.xml b/lib/ssh/doc/src/part_notes.xml
deleted file mode 100644
index aaca8ca9f2..0000000000
--- a/lib/ssh/doc/src/part_notes.xml
+++ /dev/null
@@ -1,38 +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>2016</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>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 140ebd8c76..60572b985b 100644
--- a/lib/ssh/doc/src/ref_man.xml
+++ b/lib/ssh/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -35,10 +35,12 @@
</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"/>
+ <xi:include href="ssh_file.xml"/>
<xi:include href="ssh_sftp.xml"/>
<xi:include href="ssh_sftpd.xml"/>
</application>
diff --git a/lib/ssh/doc/src/specs.xml b/lib/ssh/doc/src/specs.xml
new file mode 100644
index 0000000000..a6517f3660
--- /dev/null
+++ b/lib/ssh/doc/src/specs.xml
@@ -0,0 +1,14 @@
+<?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_file.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 ef9f7cbd9b..8435fced11 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,15 +4,15 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2016</year>
+ <year>2004</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
+
+ 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,
@@ -31,462 +31,526 @@
<module>ssh</module>
<modulesummary>Main API of the ssh application</modulesummary>
<description>
- <p>Interface module for the <c>ssh</c> application.</p>
- <p>See <seealso marker="ssh:SSH_app#supported">ssh(6)</seealso> for details of supported version,
- algorithms and unicode support.</p>
+ <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>OPTIONS</title>
- <p>The exact behaviour of some functions can be adjusted with the use of options which are documented together
- with the functions. Generally could each option be used at most one time in each function call. If given two or more
- times, the effect is not predictable unless explicitly documented.</p>
- <p>The options are of different kinds:</p>
- <taglist>
- <tag>Limits</tag>
- <item><p>which alters limits in the system, for example number of simultaneous login attempts.</p></item>
-
- <tag>Timeouts</tag>
- <item><p>which give some defined behaviour if too long time elapses before a given event or action,
- for example time to wait for an answer.</p></item>
-
- <tag>Callbacks</tag>
- <item><p>which gives the caller of the function the possibility to execute own code on some events,
- for example calling an own logging function or to perform an own login function</p></item>
-
- <tag>Behaviour</tag>
- <item><p>which changes the systems behaviour.</p></item>
- </taglist>
+ <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>
+
+ <p>The paths could easily be changed by options:
+ <seealso marker="ssh_file#type-user_dir_common_option"><c>user_dir</c></seealso> and
+ <seealso marker="ssh_file#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="ssh_file#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="ssh_file#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="ssh_file#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>
- <section>
- <title>DATA TYPES</title>
- <p>Type definitions that are used more than once in
- this module, or abstractions to indicate the intended use of the data
- type, or both:</p>
- <taglist>
- <tag><c>boolean() =</c></tag>
- <item><p><c>true | false</c></p></item>
- <tag><c>string() =</c></tag>
- <item><p><c>[byte()]</c></p></item>
- <tag><c>ssh_daemon_ref() =</c></tag>
- <item><p>opaque() -
- as returned by <c>ssh:daemon/[1,2,3]</c></p></item>
- <tag><c>ssh_connection_ref() =</c></tag>
- <item><p>opaque() - as returned by <c>ssh:connect/3</c></p></item>
- <tag><c>ip_address() =</c></tag>
- <item><p><c>inet::ip_address</c></p></item>
- <tag><c>subsystem_spec() =</c></tag>
- <item><p><c>{subsystem_name(),
- {channel_callback(), channel_init_args()}}</c></p></item>
- <tag><c>subsystem_name() =</c></tag>
- <item><p><c>string()</c></p></item>
- <tag><c>channel_callback() =</c></tag>
- <item><p><c>atom()</c> - Name of the Erlang module
- implementing the subsystem using the <c>ssh_channel</c> behavior, see
- <seealso marker="ssh_channel">ssh_channel(3)</seealso></p></item>
- <tag><c>key_cb() =</c></tag>
- <item>
- <p><c>atom() | {atom(), list()}</c></p>
- <p><c>atom()</c> - Name of the erlang module implementing the behaviours
- <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> or
- <seealso marker="ssh_client_key_api">ssh_client_key_api</seealso> as the
- case maybe.</p>
- <p><c>list()</c> - List of options that can be passed to the callback module.</p>
- </item>
- <tag><c>channel_init_args() =</c></tag>
- <item><p><c>list()</c></p></item>
-
- <tag><c>algs_list() =</c></tag>
- <item><p><c>list( alg_entry() )</c></p></item>
-
- <tag><c>alg_entry() =</c></tag>
- <item><p><c>{kex, simple_algs()} | {public_key, simple_algs()} | {cipher, double_algs()} | {mac, double_algs()} | {compression, double_algs()}</c></p></item>
-
- <tag><c>simple_algs() =</c></tag>
- <item><p><c>list( atom() )</c></p></item>
-
- <tag><c>double_algs() =</c></tag>
- <item><p><c>[{client2serverlist,simple_algs()},{server2client,simple_algs()}] | simple_algs()</c></p></item>
- </taglist>
-</section>
+ <!--
+ ================================================================
+ = Data types =
+ ================================================================
+ -->
- <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>
+ <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) -> </name>
- <name>connect(TcpSocket, Options) -> </name>
- <name>connect(TcpSocket, Options, Timeout) ->
- {ok, ssh_connection_ref()} | {error, Reason}</name>
- <fsummary>Connects to an SSH server.</fsummary>
- <type>
- <v>Host = string()</v>
- <v>Port = integer()</v>
- <d><c><![CDATA[22]]></c> is default, the assigned well-known port
- number for SSH.</d>
- <v>Options = [{Option, Value}]</v>
- <v>Timeout = infinity | integer()</v>
- <d>Negotiation time-out in milli-seconds. The default value is <c>infinity</c>.
- For connection time-out, use option <c>{connect_timeout, timeout()}</c>.</d>
- <v>TcpSocket = port()</v>
- <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</c></d>
- </type>
+ </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:</p>
<taglist>
- <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
+ <tag><c>silently_accept_hosts</c></tag>
<item>
- <p>IP version to use.</p>
- </item>
- <tag><c><![CDATA[{user_dir, string()}]]></c></tag>
- <item>
- <p>Sets the user directory, that is, the directory containing
- <c>ssh</c> configuration files for the user, such as
- <c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c>, and
- <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>
- </item>
- <tag><c><![CDATA[{rsa_pass_phrase, string()}]]></c></tag>
- <item>
- <p>If the user RSA key is protected by a passphrase, it can be
- supplied with this option.
- </p>
- </item>
- <tag><c><![CDATA[{silently_accept_hosts, boolean()}]]></c></tag>
- <item>
- <p>When <c>true</c>, hosts are added to the
- file <c><![CDATA[known_hosts]]></c> without asking the user.
- Defaults to <c>false</c>.
+ <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="ssh_file#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[{user_interaction, boolean()}]]></c></tag>
+
+ <tag><c>user_interaction</c></tag>
<item>
<p>If <c>false</c>, disables the client to connect to the server
if any user interaction is needed, such as accepting
the server to be added to the <c>known_hosts</c> file, or
- supplying a password. Defaults to <c>true</c>.
- Even if user interaction is allowed it can be
+ 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 optins are not always desirable
+ 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[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
+ <tag><c>save_accepted_host</c></tag>
<item>
- <p>Provides a fun to implement your own logging when a server disconnects the client.</p>
- </item>
-
- <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
- <item>
- <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
- If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
- report is generated.</p>
- <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
- </item>
-
- <tag><c><![CDATA[{public_key_alg, 'ssh-rsa' | 'ssh-dss'}]]></c></tag>
- <item>
- <note>
- <p>This option will be removed in OTP 20, but is kept for compatibility. It is ignored if
- the preferred <c>pref_public_key_algs</c> option is used.</p>
- </note>
- <p>Sets the preferred public key algorithm to use for user
- authentication. If the preferred algorithm fails,
- the other algorithm is tried. If <c>{public_key_alg, 'ssh-rsa'}</c> is set, it is translated
- to <c>{pref_public_key_algs, ['ssh-rsa','ssh-dss']}</c>. If it is
- <c>{public_key_alg, 'ssh-dss'}</c>, it is translated
- to <c>{pref_public_key_algs, ['ssh-dss','ssh-rsa']}</c>.
+ <p>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="ssh_file#type-user_dir_common_option"><c>user_dir</c></seealso> for
+ the location of that file.
</p>
- </item>
-
- <tag><c><![CDATA[{pref_public_key_algs, list()}]]></c></tag>
- <item>
- <p>List of user (client) public key algorithms to try to use.</p>
- <p>The default value is
- <c><![CDATA[['ssh-rsa','ssh-dss','ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521'] ]]></c>
- </p>
- <p>If there is no public key of a specified type available, the corresponding entry is ignored.</p>
- </item>
-
- <tag><c><![CDATA[{preferred_algorithms, algs_list()}]]></c></tag>
- <item>
- <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
- be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ <p>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>If an alg_entry() is missing in the algs_list(), the default value is used for that entry.</p>
- <p>Here is an example of this option:</p>
- <code>
-{preferred_algorithms,
- [{public_key,['ssh-rsa','ssh-dss']},
- {cipher,[{client2server,['aes128-ctr']},
- {server2client,['aes128-cbc','3des-cbc']}]},
- {mac,['hmac-sha2-256','hmac-sha1']},
- {compression,[none,zlib]}
- ]
-}
-</code>
- <p>The example specifies different algorithms in the two directions (client2server and server2client),
- for cipher but specifies the same algorithms for mac and compression in both directions.
- The kex (key exchange) is implicit but public_key is set explicitly.</p>
-
- <warning>
- <p>Changing the values can make a connection less secure. Do not change unless you
- know exactly what you are doing. If you do not understand the values then you
- are not supposed to change them.</p>
- </warning>
+ <p>Defaults to <c>true</c></p>
</item>
- <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),I=integer(),Max=integer()}}]]></c></tag>
+ <tag><c>quiet_mode</c></tag>
<item>
- <p>Sets the three diffie-hellman-group-exchange parameters that guides the connected server in choosing a group.
- See RFC 4419 for the function of thoose. The default value is <c>{1024, 6144, 8192}</c>.
- </p>
+ <p>If <c>true</c>, the client does not print anything on authorization.</p>
+ <p>Defaults to <c>false</c></p>
</item>
+ </taglist>
+ </desc>
+ </datatype>
- <tag><c><![CDATA[{connect_timeout, timeout()}]]></c></tag>
- <item>
- <p>Sets a time-out on the transport layer
- connection. For <c>gen_tcp</c> the time is in milli-seconds and the default value is
- <c>infinity</c>.</p>
- </item>
- <tag><c><![CDATA[{user, string()}]]></c></tag>
+ <datatype>
+ <name name="authentication_client_options"/>
+ <desc>
+ <taglist>
+ <tag><c>user</c></tag>
<item>
- <p>Provides a username. If this option is not given, <c>ssh</c>
+ <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[USERNAME]]></c> on Windows).</p>
</item>
- <tag><c><![CDATA[{password, string()}]]></c></tag>
+
+ <tag><c>password</c></tag>
<item>
<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, key_cb()}]]></c></tag>
- <item>
- <p>Module implementing the behaviour <seealso
- marker="ssh_client_key_api">ssh_client_key_api</seealso>. Can be used to
- customize the handling of public keys. If callback options are provided
- along with the module name, they are made available to the callback
- module via the options passed to it under the key 'key_cb_private'.
- </p>
- </item>
- <tag><c><![CDATA[{quiet_mode, atom() = boolean()}]]></c></tag>
- <item>
- <p>If <c>true</c>, the client does not print 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>Allows an existing file descriptor to be used
- (by passing it on to the transport protocol).</p></item>
- <tag><c><![CDATA[{rekey_limit, integer()}]]></c></tag>
- <item>
- <p>Provides, in bytes, when rekeying is to be initiated.
- Defaults to once per each GB and once per hour.</p>
- </item>
- <tag><c><![CDATA[{idle_time, integer()}]]></c></tag>
- <item>
- <p>Sets a time-out on a connection when no channels are active.
- Defaults to <c>infinity</c>.</p></item>
- <tag><c><![CDATA[{ssh_msg_debug_fun, fun(ConnectionRef::ssh_connection_ref(), AlwaysDisplay::boolean(), Msg::binary(), LanguageTag::binary()) -> _}]]></c></tag>
- <item>
- <p>Provide a fun to implement your own logging of the SSH message SSH_MSG_DEBUG. The last three parameters are from the message, see RFC4253, section 11.3. The <c>ConnectionRef</c> is the reference to the connection on which the message arrived. The return value from the fun is not checked.</p>
- <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="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>
- </taglist>
- </desc>
- </func>
+ <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>
- <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_title>Daemon Options (Server Options)</datatype_title>
+
+ <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) -> </name>
- <name>daemon(TcpSocket) -> </name>
- <name>daemon(TcpSocket, Options) -> {ok, ssh_daemon_ref()} | {error, atom()}</name>
- <fsummary>Starts a server listening for SSH connections
- on the given port.</fsummary>
- <type>
- <v>Port = integer()</v>
- <v>HostAddress = ip_address() | any</v>
- <v>Options = [{Option, Value}]</v>
- <v>Option = atom()</v>
- <v>Value = term()</v>
- <v>TcpSocket = port()</v>
- <d>The socket is supposed to be from <seealso marker="kernel:gen_tcp#connect-3">gen_tcp:connect</seealso> or <seealso marker="kernel:gen_tcp#accept-1">gen_tcp:accept</seealso> with option <c>{active,false}</c></d>
- </type>
+ <datatype>
+ <name name="subsystem_daemon_option"/>
+ <name name="subsystem_spec"/>
<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>Options:</p>
- <taglist>
- <tag><c><![CDATA[{inet, inet | inet6}]]></c></tag>
- <item><p>IP version to use when the host address is specified as <c>any</c>.</p></item>
- <tag><c><![CDATA[{subsystems, [subsystem_spec()]}]]></c></tag>
+ <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_spec"/>
+ <desc/>
+ </datatype>
+ <datatype>
+ <name name="exec_fun"/>
+ <desc/>
+ </datatype>
+ <datatype>
+ <name name="'exec_fun/1'"/>
+ <name name="'exec_fun/2'"/>
+ <name name="'exec_fun/3'"/>
+ <desc/>
+ </datatype>
+ <datatype>
+ <name name="exec_result"/>
+ <desc>
+ <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>
- <p>Provides specifications for handling of subsystems. The
- "sftp" subsystem specification is retrieved by calling
- <c>ssh_sftpd:subsystem_spec/1</c>. If the subsystems option is
- not present, the value of
- <c>[ssh_sftpd:subsystem_spec([])]</c> is used.
- The option can be set to the empty list if
- you do not want the daemon to run any subsystems.</p>
+ <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>
- <p>Defines the read-eval-print loop used when a shell is
- requested by the client. The default is to use the Erlang shell:
- <c><![CDATA[{shell, start, []}]]></c></p>
+ <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>
- <p>Provides your own CLI implementation, that is, a channel callback
- module that implements a shell and command execution. The shell
- read-eval-print loop can be customized, using the
- option <c>shell</c>. This means less work than implementing
- an own CLI channel. If set to <c>no_cli</c>, the CLI channels
- are disabled and only subsystem channels are allowed.</p>
+ <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. That is, the directory containing
- <c>ssh</c> configuration files for the user, such as
- <c><![CDATA[known_hosts]]></c>, <c><![CDATA[id_rsa,
- id_dsa]]></c>, and
- <c><![CDATA[authorized_key]]></c>. Defaults to the
- directory normally referred to as
- <c><![CDATA[~/.ssh]]></c>.</p>
- </item>
- <tag><c><![CDATA[{system_dir, string()}]]></c></tag>
- <item>
- <p>Sets the system directory, containing the host key files
- that identify the host keys for <c>ssh</c>. Defaults to
- <c><![CDATA[/etc/ssh]]></c>. For security reasons,
- this directory is normally accessible only to the root user.</p>
+ <p>The default Erlang evaluator is used and the result is returned to the client.</p>
</item>
+ </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>
- <tag><c><![CDATA[{auth_methods, string()}]]></c></tag>
- <item>
- <p>Comma-separated string that determines which
- authentication methods that the server is to support and
- in what order they are tried. Defaults to
- <c><![CDATA["publickey,keyboard-interactive,password"]]></c></p>
- </item>
+ <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>
- <tag><c><![CDATA[{auth_method_kb_interactive_data, PromptTexts}]]></c>
- <br/><c>where:</c>
- <br/><c>PromptTexts = kb_int_tuple() | fun(Peer::{IP::tuple(),Port::integer()}, User::string(), Service::string()) -> kb_int_tuple()</c>
- <br/><c>kb_int_tuple() = {Name::string(), Instruction::string(), Prompt::string(), Echo::boolean()}</c>
- </tag>
+ <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><c>auth_method_kb_interactive_data</c></tag>
<item>
- <p>Sets the text strings that the daemon sends to the client for presentation to the user when using <c>keyboar-interactive</c> authentication. If the fun/3 is used, it is called when the actual authentication occurs and may therefore return dynamic data like time, remote ip etc.</p>
+ <p>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>
+ <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><marker id="option-user_passwords"/><c>user_passwords</c></tag>
<item>
- <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
+ <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><marker id="option-password"/><c>password</c></tag>
<item>
- <p>Provides a global password that authenticates 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[{preferred_algorithms, algs_list()}]]></c></tag>
+ <tag><marker id="option-pwdfun"/><c>pwdfun</c> with
+ <seealso marker="#type-pwdfun_4"><c>pwdfun_4()</c></seealso>
+ </tag>
<item>
- <p>List of algorithms to use in the algorithm negotiation. The default <c>algs_list()</c> can
- be obtained from <seealso marker="#default_algorithms/0">default_algorithms/0</seealso>.
+ <p>Provides a function for password validation. This could used for calling an external system or handeling
+ passwords stored as hash values.
</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>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>
- <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>
+ <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[{dh_gex_groups, [{Size=integer(),G=integer(),P=integer()}] | {file,filename()} {ssh_moduli_file,filename()} }]]></c></tag>
+ <tag><c>pwdfun</c> with
+ <seealso marker="#type-pwdfun_2"><c>pwdfun_2()</c></seealso>
+ </tag>
+ <item>
+ <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>
+
+ <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>Defines the groups the server may choose among when diffie-hellman-group-exchange is negotiated.
- See RFC 4419 for details. The three variants of this option are:
+ See
+ <url href="https://tools.ietf.org/html/rfc4419">RFC 4419</url>
+ for details. The three variants of this option are:
</p>
<taglist>
<tag><c>{Size=integer(),G=integer(),P=integer()}</c></tag>
@@ -508,7 +572,7 @@
</p>
</item>
- <tag><c><![CDATA[{dh_gex_limits,{Min=integer(),Max=integer()}}]]></c></tag>
+ <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
@@ -519,57 +583,29 @@
</p>
<p>If <c>MaxUsed &lt; MinUsed</c> in a key exchange, it will fail with a disconnect.
</p>
- <p>See RFC 4419 for the function of the Max and Min values.</p>
- </item>
-
- <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string(), PeerAddress::{ip_adress(),port_number()}, State::any()) -> boolean() | disconnect | {boolean(),any()} }]]></c></tag>
- <item>
- <p>Provides a function for password validation. This could used for calling an external system or if
- passwords should be stored as a hash. The fun returns:
- </p>
- <list type="bulleted">
- <item><c>true</c> if the user and password is valid and</item>
- <item><c>false</c> otherwise.</item>
- </list>
- <p>This fun can also be used to make delays in authentication tries for example by calling
- <seealso marker="stdlib:timer#sleep/1">timer:sleep/1</seealso>. To facilitate counting of failed tries
- the <c>State</c> variable could be used. This state is per connection only. The first time the pwdfun
- is called for a connection, the <c>State</c> variable has the value <c>undefined</c>.
- The pwdfun can return - in addition to the values above - a new state
- as:
- </p>
- <list type="bulleted">
- <item><c>{true, NewState:any()}</c> if the user and password is valid or</item>
- <item><c>{false, NewState:any()}</c> if the user or password is invalid</item>
- </list>
- <p>A third usage is to block login attempts from a missbehaving peer. The <c>State</c> described above
- can be used for this. In addition to the responses above, the following return value is introduced:
- </p>
- <list type="bulleted">
- <item><c>disconnect</c> if the connection should be closed immediately after sending a SSH_MSG_DISCONNECT
- message.</item>
- </list>
- </item>
-
- <tag><c><![CDATA[{pwdfun, fun(User::string(), Password::string()) -> boolean()}]]></c></tag>
- <item>
- <p>Provides a function for password validation. This function is called
- with user and password as strings, and returns
- <c><![CDATA[true]]></c> if the password is valid and
- <c><![CDATA[false]]></c> otherwise.</p>
- <p>This option (<c>{pwdfun,fun/2}</c>) is the same as a subset of the previous
- (<c>{pwdfun,fun/4}</c>). It is kept for compatibility.</p>
+ <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[{negotiation_timeout, integer()}]]></c></tag>
- <item>
- <p>Maximum time in milliseconds for the authentication negotiation.
- Defaults to 120000 (2 minutes). If the client fails to log in within this time,
- the connection is closed.
- </p>
- </item>
+ <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>
- <tag><c><![CDATA[{max_sessions, pos_integer()}]]></c></tag>
+ <datatype>
+ <name name="hardening_daemon_options"/>
+ <desc>
+ <taglist>
+ <tag><c>max_sessions</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.
@@ -589,7 +625,7 @@
</p>
</item>
- <tag><c><![CDATA[{max_channels, pos_integer()}]]></c></tag>
+ <tag><c>max_channels</c></tag>
<item>
<p>The maximum number of channels with active remote subsystem that are accepted for
each connection to this daemon</p>
@@ -597,8 +633,7 @@
</p>
</item>
-
- <tag><c><![CDATA[{parallel_login, boolean()}]]></c></tag>
+ <tag><c>parallel_login</c></tag>
<item>
<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.
@@ -615,143 +650,562 @@
</warning>
</item>
- <tag><c><![CDATA[{minimal_remote_max_packet_size, non_negative_integer()}]]></c></tag>
+ <tag><c>minimal_remote_max_packet_size</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 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[{id_string, random | string()}]]></c></tag>
+
+ </taglist>
+ </desc>
+ </datatype>
+
+ <datatype>
+ <name name="callbacks_daemon_options"/>
+ <desc>
+ <taglist>
+ <tag><c>connectfun</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>
- <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>Provides a fun to implement your own logging when a user authenticates to the server.</p>
</item>
- <tag><c><![CDATA[{key_cb, key_cb()}]]></c></tag>
+ <tag><c>failfun</c></tag>
<item>
- <p>Module implementing the behaviour <seealso
- marker="ssh_server_key_api">ssh_server_key_api</seealso>. Can be used to
- customize the handling of public keys. If callback options are provided
- along with the module name, they are made available to the callback
- module via the options passed to it under the key 'key_cb_private'.
- </p>
+ <p>Provides a fun to implement your own logging when a user fails to authenticate.</p>
</item>
-
- <tag><c>{profile, atom()}</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="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>. See also the manpage of
+ <seealso marker="ssh:ssh_file">ssh_file</seealso>.
+ </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
+ <seealso marker="ssh:ssh#connect-3">ssh:connect</seealso>,
+ <seealso marker="ssh:ssh#shell-1">ssh:shell</seealso> or
+ <seealso marker="ssh:ssh#daemon-2">ssh:daemon</seealso>.
+ </p>
+
+ </desc>
+ </datatype>
+
+ <datatype>
+ <name name="pref_public_key_algs_common_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="ssh_file#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="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>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>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[{fd, file_descriptor()}]]></c></tag>
- <item>
- <p>Allows an existing file-descriptor to be used
- (passed on to the transport protocol).</p></item>
- <tag><c><![CDATA[{failfun, fun(User::string(),
- PeerAddress::ip_address(), Reason::term()) -> _}]]></c></tag>
<item>
- <p>Provides a fun to implement your own logging when a user fails to authenticate.</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[{connectfun, fun(User::string(), PeerAddress::ip_address(),
- Method::string()) ->_}]]></c></tag>
<item>
- <p>Provides a fun to implement your own logging when a user authenticates to the server.</p>
+ <p>Repeat the modification step with the tail of <c>modify_algs_list()</c> and the resulting
+ <c>A'</c>.
+ </p>
</item>
- <tag><c><![CDATA[{disconnectfun, fun(Reason:term()) -> _}]]></c></tag>
- <item>
- <p>Provides a fun to implement your own logging when a user disconnects from the server.</p>
+ </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>
-
- <tag><c><![CDATA[{unexpectedfun, fun(Message:term(), Peer) -> report | skip }]]></c></tag>
- <item>
- <p>Provides a fun to implement your own logging or other action when an unexpected message arrives.
- If the fun returns <c>report</c> the usual info report is issued but if <c>skip</c> is returned no
- report is generated.</p>
- <p><c>Peer</c> is in the format of <c>{Host,Port}</c>.</p>
+ <item><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>
- <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>
- </taglist>
- </desc>
- </func>
+ <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>
- <func>
- <name>daemon_info(Daemon) -> {ok, [{port,Port}]} | {error,Error}</name>
- <fsummary>Get info about a daemon</fsummary>
- <type>
- <v>Port = integer()</v>
- <v>Error = bad_daemon_ref</v>
- </type>
+ <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>
- <p>Returns a key-value list with information about the daemon. For now, only the listening port is returned. This is intended for the case the daemon is started with the port set to 0.</p>
</desc>
+ </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>default_algorithms() -> algs_list()</name>
+ <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. An example:</p>
- <code>
-20> ssh:default_algorithms().
-[{kex,['diffie-hellman-group1-sha1']},
- {public_key,['ssh-rsa','ssh-dss']},
- {cipher,[{client2server,['aes128-ctr','aes128-cbc','3des-cbc']},
- {server2client,['aes128-ctr','aes128-cbc','3des-cbc']}]},
- {mac,[{client2server,['hmac-sha2-256','hmac-sha1']},
- {server2client,['hmac-sha2-256','hmac-sha1']}]},
- {compression,[{client2server,[none,zlib]},
- {server2client,[none,zlib]}]}]
-21>
-</code>
+ 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) -> </name>
- <name>shell(Host, Option) -> </name>
- <name>shell(Host, Port, Option) -> </name>
- <name>shell(TcpSocket) -> _</name>
- <fsummary>Starts an interactive shell over an SSH server.</fsummary>
+ <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>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>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 over an SSH server on the
- given <c>Host</c>. The function waits for user input,
- and does not return until the remote shell is ended (that is,
+ <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>
+ <name name="start" arity="0"/>
+ <name name="start" arity="1"/>
<fsummary>Starts the SSH application.</fsummary>
- <type>
- <v>Type = permanent | transient | temporary</v>
- <v>Reason = term() </v>
- </type>
<desc>
<p>Utility function that starts the applications <c>crypto</c>, <c>public_key</c>,
and <c>ssh</c>. Default type is <c>temporary</c>.
@@ -761,11 +1215,8 @@
</func>
<func>
- <name>stop() -> ok | {error, Reason}</name>
+ <name name="stop" arity="0"/>
<fsummary>Stops the <c>ssh</c> application.</fsummary>
- <type>
- <v>Reason = term()</v>
- </type>
<desc>
<p>Stops the <c>ssh</c> application.
For more information, see the <seealso marker="kernel:application">application(3)</seealso>
@@ -774,34 +1225,22 @@
</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 operational.</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 operational.</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 5cc4c24889..0c22a50c3f 100644
--- a/lib/ssh/doc/src/ssh_app.xml
+++ b/lib/ssh/doc/src/ssh_app.xml
@@ -4,7 +4,7 @@
<appref>
<header>
<copyright>
- <year>2012</year><year>2016</year>
+ <year>2012</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -74,13 +74,18 @@
<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>.
+ by the options
+ <seealso marker="ssh_file#type-user_dir_common_option"><c>user_dir</c></seealso> and
+ <seealso marker="ssh_file#type-system_dir_daemon_option"><c>system_dir</c></seealso>.
</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>
+ <p>See also the default callback module documentation in
+ <seealso marker="ssh_file">ssh_file</seealso>.
+ </p>
</section>
<section>
@@ -97,7 +102,7 @@
<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>
+ </p>
</section>
<section>
<title>Authorized Keys</title>
@@ -109,7 +114,7 @@
</section>
<section>
<title>Host Keys</title>
- <p>RSA and DSA host keys are supported and are
+ <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>
@@ -130,33 +135,51 @@
For the list on a particular installation, use the command
<seealso marker="ssh:ssh#default_algorithms/0">ssh:default_algorithms/0</seealso>.
The user may override the default algorithm configuration both on the server side and the client side.
- See the option <c>preferred_algorithms</c> in the <seealso marker="ssh:ssh#daemon/1">ssh:daemon/1,2,3</seealso> and
+ 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:</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-nistp256</item>
<item>ecdh-sha2-nistp384</item>
<item>ecdh-sha2-nistp521</item>
- <item>diffie-hellman-group-exchange-sha1</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-group1-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-nistp256</item>
<item>ecdsa-sha2-nistp384</item>
<item>ecdsa-sha2-nistp521</item>
+ <item>ecdsa-sha2-nistp256</item>
+ <item>ssh-ed25519</item>
+ <item>ssh-ed448</item>
<item>ssh-rsa</item>
+ <item>rsa-sha2-256</item>
+ <item>rsa-sha2-512</item>
<item>ssh-dss</item>
</list>
</item>
@@ -173,21 +196,24 @@
<tag>Encryption algorithms (ciphers)</tag>
<item>
<list type="bulleted">
- <item>[email protected] (AEAD_AES_128_GCM)</item>
- <item>[email protected] (AEAD_AES_256_GCM)</item>
- <item>aes128-ctr</item>
- <item>aes192-ctr</item>
+ <item>[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>
- <p>See the text at the description of <seealso marker="#rfc5647_note">the rfc 5647 further down</seealso>
- for more information.
- </p>
</item>
<tag>Compression algorithms</tag>
@@ -232,7 +258,15 @@
</item>
<item><url href="https://tools.ietf.org/html/rfc4253">RFC 4253</url>, The Secure Shell (SSH) Transport Layer Protocol.
- <p></p>
+ <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.
@@ -269,7 +303,10 @@
<p><marker id="rfc5647_note"/>There is an ambiguity in the synchronized selection of cipher and mac algorithm.
This is resolved by OpenSSH in the ciphers [email protected] and [email protected] which are implemented.
If the explicit ciphers and macs AEAD_AES_128_GCM or AEAD_AES_256_GCM are needed,
- they could be enabled with the option preferred_algorithms.
+ 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>
<warning>
<p>
@@ -306,7 +343,48 @@
<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>
+
+ <item>
+ <url href="https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-ed448">Ed25519 and Ed448 public key algorithms for the Secure Shell (SSH) protocol (work in progress)</url>
+ </item>
+
</list>
</section>
diff --git a/lib/ssh/doc/src/ssh_channel.xml b/lib/ssh/doc/src/ssh_client_channel.xml
index 7b598494f7..9be4007c68 100644
--- a/lib/ssh/doc/src/ssh_channel.xml
+++ b/lib/ssh/doc/src/ssh_client_channel.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2009</year>
- <year>2016</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -23,21 +23,27 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>ssh_channel</title>
+ <title>ssh_client_channel</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
</header>
- <module>ssh_channel</module>
- <modulesummary>-behaviour(ssh_channel).
+ <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, such as flow control
+ 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
@@ -46,41 +52,19 @@
the <c>ssh</c> applications supervisor tree.
</p>
- <note><p>When implementing an <c>ssh</c> subsystem, use
- <c>-behaviour(ssh_daemon_channel)</c> instead of <c>-behaviour(ssh_channel)</c>.
- The reason is that the only relevant callback functions for subsystems are
- <c>init/1</c>, <c>handle_ssh_msg/2</c>, <c>handle_msg/2</c>, and <c>terminate/2</c>.
- So, the <c>ssh_daemon_channel</c> behaviour is a limited version of the
- <c>ssh_channel</c> behaviour.
- </p></note>
- </description>
+ <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>
- <section>
- <title>DATA TYPES</title>
+ <dont>
+ <p>Functions in this module are not supposed to be called outside a module implementing this
+ behaviour!
+ </p>
+ </dont>
- <p>Type definitions that are used more than once in this module,
- or abstractions to indicate the intended use of the data
- type, or both:</p>
-
- <taglist>
- <tag><c>boolean() =</c></tag>
- <item><p><c>true | false</c></p></item>
- <tag><c>string() =</c></tag>
- <item><p>list of ASCII characters</p></item>
- <tag><c>timeout() =</c></tag>
- <item><p><c>infinity | integer()</c> in milliseconds</p></item>
- <tag><c>ssh_connection_ref() =</c></tag>
- <item><p>opaque() -as returned by
- <c>ssh:connect/3</c> or sent to an SSH channel process</p></item>
- <tag><c>ssh_channel_id() =</c></tag>
- <item><p><c>integer()</c></p></item>
- <tag><c>ssh_data_type_code() =</c></tag>
- <item><p><c>1</c> ("stderr") | <c>0</c> ("normal") are
- the valid values,
- see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
- Section 5.2</p></item>
- </taglist>
- </section>
+ </description>
<funcs>
<func>
@@ -89,7 +73,7 @@
<fsummary>Makes a synchronous call to a channel.</fsummary>
<type>
<v>ChannelRef = pid() </v>
- <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <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>
@@ -113,7 +97,7 @@
ChannelRef and returns ok.</fsummary>
<type>
<v>ChannelRef = pid()</v>
- <d>As returned by <seealso marker = "#start_link-4">ssh_channel:start_link/4</seealso></d>
+ <d>As returned by <seealso marker = "#start_link-4">start_link/4</seealso></d>
<v>Msg = term()</v>
</type>
<desc>
@@ -126,29 +110,29 @@
</desc>
</func>
- <func>
+ <func>
<name>enter_loop(State) -> _ </name>
- <fsummary>Makes an existing process an ssh_channel process.</fsummary>
+ <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">ssh_channel:init/1</seealso></d>
+ <d>as returned by <seealso marker = "#init-1">init/1</seealso></d>
</type>
<desc>
- <p>Makes an existing process an <c>ssh_channel</c>
+ <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_channel</c> process receive loop and become an
- <c>ssh_channel process</c>. The process must have been started using
+ 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">ssh_channel:init/1</seealso>.
+ 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_channel</c> process.</fsummary>
+ <fsummary>Initiates an <c>ssh_client_channel</c> process.</fsummary>
<type>
<v>Options = [{Option, Value}]</v>
<v>State = term()</v>
@@ -160,18 +144,21 @@
The following options must be present:
</p>
<taglist>
- <tag><c><![CDATA[{channel_cb, atom()}]]></c></tag>
+ <tag><c>{channel_cb, atom()}</c></tag>
<item><p>The module that implements the channel behaviour.</p></item>
- <tag><c><![CDATA[{init_args(), list()}]]></c></tag>
+ <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><![CDATA[{cm, 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>{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><![CDATA[{channel_id, channel_id()}]]></c></tag>
- <item><p>Id of the <c>ssh</c> channel.</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>
@@ -179,8 +166,8 @@
user. The user only needs to call if the
channel process needs to be started with help of
<c>proc_lib</c> instead of calling
- <c>ssh_channel:start/4</c> or
- <c>ssh_channel:start_link/4</c>.</p>
+ <c>start/4</c> or
+ <c>start_link/4</c>.</p>
</note>
</desc>
</func>
@@ -201,26 +188,31 @@
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">ssh_channel:call/[2,3].</seealso></p>
+ <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>
- <v>ChannelId = ssh_channel_id()</v>
+ <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>
@@ -235,13 +227,19 @@
</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>
- <title>CALLBACK TIME-OUTS</title>
-
- <p>The time-out values that can be returned by the callback functions
- have the same semantics as in a <seealso marker="stdlib:gen_server">gen_server</seealso>.
- If the time-out occurs, <seealso marker="#Module:handle_msg-2">handle_msg/2</seealso>
- is called as <c>handle_msg(timeout, State)</c>.</p>
+ <section>
+ <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>
@@ -295,7 +293,7 @@
initial channel state if the initializations succeed.</fsummary>
<type>
<v>Args = term()</v>
- <d>Last argument to <c>ssh_channel:start_link/4</c>.</d>
+ <d>Last argument to <c>start_link/4</c>.</d>
<v>State = term()</v>
<v>Reason = term()</v>
</type>
@@ -304,41 +302,41 @@
state if the initializations succeed.
</p>
<p>For more detailed information on time-outs, see Section
- <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>. </p>
+ <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>
+ <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">ssh_channel:reply/2</seealso></d>
+ <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">ssh_channel:call/[2,3]</seealso></d>
+ <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">ssh_channel:call/[2,3]</seealso>
+ <seealso marker="#call-2">call/[2,3]</seealso>
</p>
<p>For more detailed information on time-outs,, see Section
- <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
+ <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>
+ <c>cast/2</c>.</fsummary>
<type>
<v>Msg = term()</v>
<v>State = term()</v>
@@ -349,10 +347,10 @@
</type>
<desc>
<p>Handles messages sent by calling
- <c>ssh_channel:cast/2</c>.
+ <c>cast/2</c>.
</p>
<p>For more detailed information on time-outs, see Section
- <seealso marker="#cb_timeouts">CALLBACK TIME-OUTS</seealso>.</p>
+ <seealso marker="#cb_timeouts">Callback timeouts</seealso>.</p>
</desc>
</func>
@@ -364,7 +362,7 @@
call, or cast messages sent to the channel.</fsummary>
<type>
<v>Msg = timeout | term()</v>
- <v>ChannelId = ssh_channel_id()</v>
+ <v>ChannelId = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v>
<v>State = term() </v>
</type>
<desc>
@@ -376,11 +374,10 @@
function and all channels are to handle the following message.</p>
<taglist>
- <tag><c><![CDATA[{ssh_channel_up, ssh_channel_id(),
- ssh_connection_ref()}]]></c></tag>
+ <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">ssh_channel:init/1</seealso> function
+ 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
@@ -397,7 +394,7 @@
<fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary>
<type>
<v>Msg = ssh_connection:event()</v>
- <v>ChannelId = ssh_channel_id()</v>
+ <v>ChannelId = <seealso marker="ssh#type-channel_id">ssh:channel_id()</seealso></v>
<v>State = term()</v>
</type>
<desc>
@@ -407,10 +404,10 @@
</p>
<p>The following message is taken care of by the
- <c>ssh_channel</c> behavior.</p>
+ <c>ssh_client_channel</c> behavior.</p>
<taglist>
- <tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
+ <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>
diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml
index a1cd9d4b02..bc77756147 100644
--- a/lib/ssh/doc/src/ssh_client_key_api.xml
+++ b/lib/ssh/doc/src/ssh_client_key_api.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2012</year>
- <year>2016</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -41,7 +41,7 @@
see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
- <section>
+ <!-- section>
<title>DATA TYPES</title>
<p>Type definitions that are used more than once in this module,
@@ -56,28 +56,46 @@
<tag><c>string() =</c></tag>
<item><p><c>[byte()]</c></p></item>
<tag><c>public_key() =</c></tag>
- <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <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'{} | term()</c></p></item>
+ <item><p><c>#'RSAPrivateKey'{}
+ | #'DSAPrivateKey'{}
+ | #'ECPrivateKey'{}</c></p></item>
<tag><c>public_key_algorithm() =</c></tag>
- <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ <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>
+ </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>
+ <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>
@@ -88,18 +106,16 @@
<name>Module:is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name>
<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>
- <v>Algorithm = public_key_algorithm()</v>
- <d>Host key algorithm. Is to support <c>'ssh-rsa'| 'ssh-dss'</c>, but more 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>
</type>
@@ -110,17 +126,15 @@
<func>
<name>Module:user_key(Algorithm, ConnectOptions) ->
- {ok, PrivateKey} | {error, Reason}</name>
+ {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. Is to support <c>'ssh-rsa'| 'ssh-dss'</c> but more 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>
+ <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>
diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml
index 150d46a9a2..8e1cf156a8 100644
--- a/lib/ssh/doc/src/ssh_connection.xml
+++ b/lib/ssh/doc/src/ssh_connection.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2008</year>
- <year>2015</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -43,10 +43,10 @@
which are received as messages by the remote channel.
If the receiving channel is an Erlang process, the
messages have the format
- <c><![CDATA[{ssh_cm, ssh_connection_ref(), ssh_event_msg()}]]></c>.
- If the <seealso marker="ssh_channel">ssh_channel</seealso> behavior is used to
+ <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_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2</seealso>.</p>
+ <seealso marker="ssh_client_channel#Module:handle_ssh_msg-2">handle_ssh_msg/2</seealso>.</p>
</description>
<section>
@@ -63,10 +63,10 @@
<item><p>list of ASCII characters</p></item>
<tag><c>timeout() =</c></tag>
<item><p><c>infinity | integer()</c> in milliseconds</p></item>
- <tag><c>ssh_connection_ref() =</c></tag>
+ <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>ssh_channel_id() =</c></tag>
+ <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
@@ -75,7 +75,7 @@
<tag><c>ssh_request_status() =</c></tag>
<item><p> <c>success | failure</c></p></item>
<tag><c>event() =</c></tag>
- <item><p><c>{ssh_cm, ssh_connection_ref(), ssh_event_msg()}</c></p></item>
+ <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>
@@ -86,12 +86,12 @@
<tag><em>data_events()</em></tag>
<item>
<taglist>
- <tag><c><![CDATA[{data, ssh_channel_id(), ssh_data_type_code(), Data :: binary()}]]></c></tag>
+ <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, ssh_channel_id()}]]></c></tag>
+ <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>.
@@ -103,7 +103,7 @@
<item>
<taglist>
- <tag><c><![CDATA[{signal, ssh_channel_id(), ssh_signal()}]]></c></tag>
+ <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
@@ -111,7 +111,7 @@
referred to are on OS-level and not something generated by an
Erlang program.</p></item>
- <tag><c><![CDATA[{exit_signal, ssh_channel_id(), ExitSignal :: string(), ErrorMsg ::string(),
+ <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.
@@ -119,7 +119,7 @@
values, see <url href="http://www.ietf.org/rfc/rfc4254.txt">RFC 4254</url>
Section 6.10, which shows a special case of these signals.</p></item>
- <tag><c><![CDATA[{exit_status, ssh_channel_id(), ExitStatus :: integer()}]]></c></tag>
+ <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 <c>exit_status</c> usually means that the command
@@ -127,11 +127,11 @@
<seealso marker="ssh_connection#exit_status-3">
ssh_connection:exit_status/3</seealso>.</p></item>
- <tag><c><![CDATA[{closed, ssh_channel_id()}]]></c></tag>
+ <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_channel">ssh_channel</seealso> behavior.</p></item>
+ <seealso marker="ssh_client_channel">ssh_client_channel</seealso> behavior.</p></item>
</taglist>
</item>
@@ -149,14 +149,14 @@
with the boolean value of <c>WantReply</c> as the second argument.</p>
<taglist>
- <tag><c><![CDATA[{env, ssh_channel_id(), WantReply :: boolean(),
+ <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, ssh_channel_id(),
+ <tag><c><![CDATA[{pty, channel_id(),
WantReply :: boolean(), {Terminal :: string(), CharWidth :: integer(),
RowHeight :: integer(), PixelWidth :: integer(), PixelHeight :: integer(),
TerminalModes :: [{Opcode :: atom() | integer(),
@@ -181,13 +181,13 @@
<seealso marker="ssh_connection#shell-2"> ssh_connection:shell/2</seealso>.
</p></item>
- <tag><c><![CDATA[{window_change, ssh_channel_id(), CharWidth() :: integer(),
+ <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(),
+ <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
@@ -204,18 +204,18 @@
<name>adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok</name>
<fsummary>Adjusts the SSH flow control window.</fsummary>
<type>
- <v>ConnectionRef = ssh_connection_ref()</v>
- <v>ChannelId = ssh_channel_id()</v>
+ <v>ConnectionRef = connection_ref()</v>
+ <v>ChannelId = channel_id()</v>
<v>NumOfBytes = integer()</v>
</type>
<desc>
<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</seealso>
+ <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_channel#Module:handle_ssh_msg-2">
+ 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>
@@ -224,17 +224,17 @@
<name>close(ConnectionRef, ChannelId) -> ok</name>
<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>
- <note><p>This function is called by the <c>ssh_channel</c>
+ <note><p>This function is called by the <c>ssh_client_channel</c>
behavior when the channel is terminated, see <seealso
- marker="ssh_channel"> ssh_channel(3)</seealso>. Thus, channels implemented
+ 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>
@@ -244,8 +244,8 @@
{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>ConnectionRef = connection_ref()</v>
+ <v>ChannelId = channel_id()</v>
<v>Command = string()</v>
<v>Timeout = timeout()</v>
</type>
@@ -256,28 +256,28 @@
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(), Data :: binary()}}</c></tag>
+ <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>
+ <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(), ExitSignal :: string(), ErrorMsg :: string(), LanguageString :: string()}}</c></tag>
+ 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(), ExitStatus :: integer()}}</c></tag>
+ <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, ssh_connection_ref(),
- {closed, ssh_channel_id()}}</c></tag>
- <item><p>Indicates that the <c>ssh_channel</c> started for the
+ <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>
@@ -287,8 +287,8 @@
<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>ConnectionRef = connection_ref() </v>
+ <v>ChannelId = channel_id()</v>
<v>Status = integer()</v>
</type>
<desc>
@@ -304,8 +304,8 @@
<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>ConnectionRef = connection_ref()</v>
+ <v>ChannelId = channel_id()</v>
<v>Options = proplists:proplist()</v>
</type>
<desc>
@@ -342,10 +342,10 @@
<name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name>
<fsummary>Sends status replies to requests that want such replies.</fsummary>
<type>
- <v>ConnectionRef = ssh_connection_ref()</v>
+ <v>ConnectionRef = connection_ref()</v>
<v>WantReply = boolean()</v>
<v>Status = ssh_request_status()</v>
- <v>ChannelId = ssh_channel_id()</v>
+ <v>ChannelId = channel_id()</v>
</type>
<desc>
<p>Sends status replies to requests where the requester has
@@ -364,8 +364,8 @@
ok | {error, timeout} | {error, closed}</name>
<fsummary>Sends channel data.</fsummary>
<type>
- <v>ConnectionRef = ssh_connection_ref()</v>
- <v>ChannelId = ssh_channel_id()</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>
@@ -383,8 +383,8 @@
<name>send_eof(ConnectionRef, ChannelId) -> ok | {error, closed}</name>
<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 channel <c>ChannelId</c>.</p>
@@ -394,10 +394,10 @@
<func>
<name>session_channel(ConnectionRef, Timeout) -></name>
<name>session_channel(ConnectionRef, InitialWindowSize,
- MaxPacketSize, Timeout) -> {ok, ssh_channel_id()} | {error, reason()}</name>
+ 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>ConnectionRef = connection_ref()</v>
<v>InitialWindowSize = integer()</v>
<v>MaxPacketSize = integer()</v>
<v>Timeout = timeout()</v>
@@ -415,8 +415,8 @@
<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>ConnectionRef = connection_ref()</v>
+ <v>ChannelId = channel_id()</v>
<v>Var = string()</v>
<v>Value = string()</v>
<v>Timeout = timeout()</v>
@@ -428,18 +428,22 @@
</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 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>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>
@@ -448,8 +452,8 @@
{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>ConnectionRef = connection_ref()</v>
+ <v>ChannelId = channel_id()</v>
<v>Subsystem = string()</v>
<v>Timeout = timeout()</v>
</type>
diff --git a/lib/ssh/doc/src/ssh_file.xml b/lib/ssh/doc/src/ssh_file.xml
new file mode 100644
index 0000000000..6681d9c306
--- /dev/null
+++ b/lib/ssh/doc/src/ssh_file.xml
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2018</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>ssh_file</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>ssh_file</module>
+ <modulesummary>Default callback module for the client's and server's database operations in the ssh application</modulesummary>
+ <description>
+ <p>This module is the default callback handler for the client's and the server's user and host "database" operations.
+ All data, for instance key pairs, are stored in files in the normal file system. This page documents the files, where they
+ are stored and configuration options for this callback module.
+ </p>
+ <p>The intention is to be compatible with the
+ <url href="http://www.openssh.com">OpenSSH</url>
+ storage in files. Therefore it mimics directories and filenames of
+ <url href="http://www.openssh.com">OpenSSH</url>.
+ </p>
+
+ <p>Ssh_file implements the <seealso marker="ssh:ssh_server_key_api">ssh_server_key_api</seealso> and
+ the <seealso marker="ssh:ssh_client_key_api">ssh_client_key_api</seealso>.
+ This enables the user to make an own interface using for example a database handler.
+ </p>
+ <p>Such another callback module could be used by setting the option
+ <seealso marker="ssh:ssh#type-key_cb_common_option"><c>key_cb</c></seealso>
+ when starting a client or a server (with for example
+ <seealso marker="ssh:ssh#connect-3">ssh:connect</seealso>,
+ <seealso marker="ssh:ssh#daemon-2">ssh:daemon</seealso> of
+ <seealso marker="ssh:ssh#shell-1">ssh:shell</seealso>
+ ).
+ </p>
+
+ <note>
+ <p>The functions are <i>Callbacks</i> for the SSH app. They are not intended to be called from the user's code!
+ </p>
+ </note>
+ </description>
+
+ <section>
+ <title>Files, directories and who uses them</title>
+ <section>
+ <title>Daemons</title>
+ <p>Daemons uses all files stored in the <seealso marker="#SYSDIR">SYSDIR</seealso> directory.
+ </p>
+ <p>Optionaly, in case of <c>publickey</c> authorization, one or more of the remote user's public keys
+ in the <seealso marker="#USERDIR">USERDIR</seealso> directory are used.
+ See the files
+ <seealso marker="#USERDIR-authorized_keys"><c>USERDIR/authorized_keys</c></seealso> and
+ <seealso marker="#USERDIR-authorized_keys2"><c>USERDIR/authorized_keys2</c></seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Clients</title>
+ <p>Clients uses all files stored in the <seealso marker="#USERDIR">USERDIR</seealso> directory.
+ </p>
+ </section>
+
+ <section>
+ <title>Directory contents</title>
+ <taglist>
+ <tag><marker id="LOCALUSER"/>LOCALUSER</tag>
+ <item><p>The user name of the OS process running the Erlang virtual machine (emulator).</p>
+ </item>
+
+ <tag><marker id="SYSDIR"/>SYSDIR</tag>
+ <item><p>This is the directory holding the server's files:</p>
+ <list>
+ <item><marker id="SYSDIR-ssh_host_dsa_key"/><c>ssh_host_dsa_key</c> - private dss host key (optional)</item>
+ <item><marker id="SYSDIR-ssh_host_rsa_key"/><c>ssh_host_rsa_key</c> - private rsa host key (optional)</item>
+ <item><marker id="SYSDIR-ssh_host_ecdsa_key"/><c>ssh_host_ecdsa_key</c> - private ecdsa host key (optional)</item>
+ <item><marker id="SYSDIR-ssh_host_ed25519_key"/><c>ssh_host_ed25519_key</c> - private eddsa host key for curve 25519 (optional)</item>
+ <item><marker id="SYSDIR-ssh_host_ed448_key"/><c>ssh_host_ed448_key</c> - private eddsa host key for curve 448 (optional)</item>
+ </list>
+ <p>At least one host key must be defined. The default value of SYSDIR is <marker id="#/etc/ssh"/><c>/etc/ssh</c>.
+ </p>
+ <p>For security reasons, this directory is normally accessible only to the root user.
+ </p>
+ <p>To change the SYSDIR, see the <seealso marker="#type-system_dir_daemon_option">system_dir</seealso> option.
+ </p>
+ </item>
+
+ <tag><marker id="USERDIR"/>USERDIR</tag>
+ <item><p>This is the directory holding the files:</p>
+ <list>
+ <item><marker id="USERDIR-authorized_keys"/><c>authorized_keys</c>
+ and, as second alternative
+ <marker id="USERDIR-authorized_keys2"/><c>authorized_keys2</c> -
+ the user's public keys are stored concatenated in one of those files.
+ </item>
+ <item><marker id="USERDIR-known_hosts"/><c>known_hosts</c> - host keys from hosts visited
+ concatenated. The file is created and used by the client.</item>
+ <item><marker id="USERDIR-id_dsa"/><c>id_dsa</c> - private dss user key (optional)</item>
+ <item><marker id="USERDIR-id_rsa"/><c>id_rsa</c> - private rsa user key (optional)</item>
+ <item><marker id="USERDIR-id_ecdsa"/><c>id_ecdsa</c> - private ecdsa user key (optional)</item>
+ <item><marker id="USERDIR-id_ed25519"/><c>id_ed25519</c> - private eddsa user key for curve 25519 (optional)</item>
+ <item><marker id="USERDIR-id_ed448"/><c>id_ed448</c> - private eddsa user key for curve 448 (optional)</item>
+ </list>
+ <p>The default value of USERDIR is <c>/home/</c><seealso marker="#LOCALUSER"><c>LOCALUSER</c></seealso><c>/.ssh</c>.
+ </p>
+ <p>To change the USERDIR, see the <seealso marker="#type-user_dir_common_option">user_dir</seealso> option
+ </p>
+ </item>
+ </taglist>
+ </section>
+ </section>
+
+ <datatypes>
+ <datatype_title>Options for the default ssh_file callback module</datatype_title>
+ <datatype>
+ <name name="user_dir_common_option"/>
+ <desc>
+ <p>Sets the <seealso marker="#USERDIR">user directory</seealso>.</p>
+ </desc>
+ </datatype>
+
+ <datatype>
+ <name name="user_dir_fun_common_option"/>
+ <name name="user2dir"/>
+ <desc>
+ <p>Sets the <seealso marker="#USERDIR">user directory</seealso> dynamically
+ by evaluating the <c>user2dir</c> function.
+ </p>
+ </desc>
+ </datatype>
+
+ <datatype>
+ <name name="system_dir_daemon_option"/>
+ <desc>
+ <p>Sets the <seealso marker="#SYSDIR">system directory</seealso>.</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>
+ <p>Note that EdDSA passhrases (Curves 25519 and 448) are not implemented.</p>
+ </desc>
+ </datatype>
+
+ </datatypes>
+
+ <funcs>
+ <func>
+ <name>host_key(Algorithm, DaemonOptions) -> {ok, Key} | {error, Reason}</name>
+ <fsummary></fsummary>
+ <desc>
+ <p><strong>Types and description</strong></p>
+ <p>See the api description in
+ <seealso marker="ssh:ssh_server_key_api#Module:host_key-2">ssh_server_key_api, Module:host_key/2</seealso>.
+ </p>
+ <p><strong>Options</strong></p>
+ <list>
+ <item><seealso marker="#type-system_dir_daemon_option">system_dir</seealso></item>
+ <!-- item>dsa_pass_phrase</item -->
+ <!-- item>rsa_pass_phrase</item -->
+ <!-- item>ecdsa_pass_phrase</item -->
+ </list>
+ <p><strong>Files</strong></p>
+ <list>
+ <item><seealso marker="#SYSDIR-ssh_host_rsa_key"><c>SYSDIR/ssh_host_rsa_key</c></seealso></item>
+ <item><seealso marker="#SYSDIR-ssh_host_dsa_key"><c>SYSDIR/ssh_host_dsa_key</c></seealso></item>
+ <item><seealso marker="#SYSDIR-ssh_host_ecdsa_key"><c>SYSDIR/ssh_host_ecdsa_key</c></seealso></item>
+ <item><seealso marker="#SYSDIR-ssh_host_ed25519_key"><c>SYSDIR/ssh_host_ed25519_key</c></seealso></item>
+ <item><seealso marker="#SYSDIR-ssh_host_ed448_key"><c>SYSDIR/ssh_host_ed448_key</c>c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name>is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name>
+ <fsummary></fsummary>
+ <desc>
+ <p><strong>Types and description</strong></p>
+ <p>See the api description in
+ <seealso marker="ssh:ssh_server_key_api#Module:is_auth_key-3">ssh_server_key_api: Module:is_auth_key/3</seealso>.
+ </p>
+ <p><strong>Options</strong></p>
+ <list>
+ <item><seealso marker="#type-user_dir_fun_common_option">user_dir_fun</seealso></item>
+ <item><seealso marker="#type-user_dir_common_option">user_dir</seealso></item>
+ </list>
+ <p><strong>Files</strong></p>
+ <list>
+ <item><seealso marker="#USERDIR-authorized_keys"><c>USERDIR/authorized_keys</c></seealso></item>
+ <item><seealso marker="#USERDIR-authorized_keys2"><c>USERDIR/authorized_keys2</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name>add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name>
+ <fsummary></fsummary>
+ <desc>
+ <p><strong>Types and description</strong></p>
+ <p>See the api description in
+ <seealso marker="ssh:ssh_client_key_api#Module:add_host_key-3">ssh_client_key_api, Module:add_host_key/3</seealso>.
+ </p>
+ <p><strong>Option</strong></p>
+ <list>
+ <item><seealso marker="#type-user_dir_common_option">user_dir</seealso></item>
+ </list>
+ <p><strong>File</strong></p>
+ <list>
+ <item><seealso marker="#USERDIR-known_hosts"><c>USERDIR/known_hosts</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name>is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name>
+ <fsummary></fsummary>
+ <desc>
+ <p><strong>Types and description</strong></p>
+ <p>See the api description in
+ <seealso marker="ssh:ssh_client_key_api#Module:is_host_key-4">ssh_client_key_api, Module:is_host_key/4</seealso>.
+ </p>
+ <p><strong>Option</strong></p>
+ <list>
+ <item><seealso marker="#type-user_dir_common_option">user_dir</seealso></item>
+ </list>
+ <p><strong>File</strong></p>
+ <list>
+ <item><seealso marker="#USERDIR-known_hosts"><c>USERDIR/known_hosts</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ <func>
+ <name>user_key(Algorithm, ConnectOptions) -> {ok, PrivateKey} | {error, Reason}</name>
+ <fsummary></fsummary>
+ <desc>
+ <p><strong>Types and description</strong></p>
+ <p>See the api description in
+ <seealso marker="ssh:ssh_client_key_api#Module:user_key-2">ssh_client_key_api, Module:user_key/2</seealso>.
+ </p>
+ <p><strong>Options</strong></p>
+ <list>
+ <item><seealso marker="#type-user_dir_common_option">user_dir</seealso></item>
+ <item><seealso marker="#type-pubkey_passphrase_client_options">dsa_pass_phrase</seealso></item>
+ <item><seealso marker="#type-pubkey_passphrase_client_options">rsa_pass_phrase</seealso></item>
+ <item><seealso marker="#type-pubkey_passphrase_client_options">ecdsa_pass_phrase</seealso></item>
+ </list>
+ <p>Note that EdDSA passhrases (Curves 25519 and 448) are not implemented.</p>
+ <p><strong>Files</strong></p>
+ <list>
+ <item><seealso marker="#USERDIR-id_dsa"><c>USERDIR/id_dsa</c></seealso></item>
+ <item><seealso marker="#USERDIR-id_rsa"><c>USERDIR/id_rsa</c></seealso></item>
+ <item><seealso marker="#USERDIR-id_ecdsa"><c>USERDIR/id_ecdsa</c></seealso></item>
+ <item><seealso marker="#USERDIR-id_ed25519"><c>USERDIR/id_ed25519</c></seealso></item>
+ <item><seealso marker="#USERDIR-id_ed448"><c>USERDIR/id_ed448</c></seealso></item>
+ </list>
+ </desc>
+ </func>
+
+ </funcs>
+
+</erlref>
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 a0694ca8d9..e2a31bd5f5 100644
--- a/lib/ssh/doc/src/ssh_server_key_api.xml
+++ b/lib/ssh/doc/src/ssh_server_key_api.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2012</year>
- <year>2015</year>
+ <year>2018</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
@@ -41,7 +41,7 @@
see the <seealso marker="SSH_app"> ssh(6)</seealso> application manual.</p>
</description>
- <section>
+ <!-- section>
<title>DATA TYPES</title>
<p>Type definitions that are used more than once in this module,
@@ -57,27 +57,52 @@
<tag><c>string() =</c></tag>
<item><p><c>[byte()]</c></p></item>
<tag><c>public_key() =</c></tag>
- <item><p><c>#'RSAPublicKey'{}| {integer(), #'Dss-Parms'{}}| term()</c></p></item>
+ <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'{} | term()</c></p></item>
+ <item><p><c>#'RSAPrivateKey'{}
+ | #'DSAPrivateKey'{}
+ | #'ECPrivateKey'{}</c></p></item>
<tag><c>public_key_algorithm() =</c></tag>
- <item><p><c>'ssh-rsa'| 'ssh-dss' | atom()</c></p></item>
+ <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>
+ </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 host’s private key.</fsummary>
<type>
- <v>Algorithm = public_key_algorithm()</v>
- <d>Host key algorithm. Is to support <c>'ssh-rsa' | 'ssh-dss'</c>, but more algorithms
- can be handled.</d>
- <v>DaemonOptions = proplists:proplist()</v>
- <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
- <v>Key = private_key()</v>
- <d>Private key of the host matching the <c>Algorithm</c>.</d>
+ <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>
@@ -86,15 +111,17 @@
</func>
<func>
- <name>Module:is_auth_key(Key, User, DaemonOptions) -> Result</name>
+ <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>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 = proplists:proplist()</v>
- <d>Options provided to <seealso marker="ssh#daemon-2">ssh:daemon/[2,3]</seealso>.</d>
+
+ <v>DaemonOptions = <seealso marker="#type-daemon_key_cb_options">daemon_key_cb_options()</seealso></v>
+
<v>Result = boolean()</v>
</type>
<desc>
diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml
index eb6f43d417..8c105147d6 100644
--- a/lib/ssh/doc/src/ssh_sftp.xml
+++ b/lib/ssh/doc/src/ssh_sftp.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2016</year>
+ <year>2005</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -46,9 +46,9 @@
<taglist>
<tag><c>reason()</c></tag>
<item>
- <p>= <c>atom()</c> A description of the reason why an operation failed.</p>
+ <p>= <c>atom() | string() | tuple() </c>A description of the reason why an operation failed.</p>
<p>
- The value is formed from the sftp error codes in the protocol-level responses as defined in
+ 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>
@@ -57,9 +57,13 @@
E.g. the error code <c>SSH_FX_NO_SUCH_FILE</c>
will cause the <c>reason()</c> to be <c>no_such_file</c>.
</p>
+ <p>The <c>string()</c> reason is the error information from the server in case of an exit-signal. If that information is empty, the reason is the exit signal name.
+ </p>
+ <p>The <c>tuple()</c> reason are other errors like the <c>{exit_status,integer()}</c> if the exit status is not 0.
+ </p>
</item>
- <tag><c>ssh_connection_ref() =</c></tag>
+ <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>
@@ -421,7 +425,6 @@
<type>
<v>ChannelPid = pid()</v>
<v>Handle = term()</v>
- <v>Position = integer()</v>
<v>Len = integer()</v>
<v>Timeout = timeout()</v>
<v>Data = string() | binary()</v>
@@ -464,11 +467,16 @@
<v>FileInfo = record()</v>
</type>
<desc>
- <p>Returns a <c><![CDATA[file_info]]></c> record from the file specified by
+ <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>
@@ -541,7 +549,7 @@
<fsummary>Starts an SFTP client.</fsummary>
<type>
<v>Host = string()</v>
- <v>ConnectionRef = ssh_connection_ref()</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>
@@ -558,8 +566,14 @@
<taglist>
<tag><c><![CDATA[{timeout, timeout()}]]></c></tag>
<item>
- <p>The time-out is passed to the <c>ssh_channel</c> start function,
- and defaults to <c>infinity</c>.</p>
+ <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>
diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml
index 1be29b3b29..3b34150e98 100644
--- a/lib/ssh/doc/src/ssh_sftpd.xml
+++ b/lib/ssh/doc/src/ssh_sftpd.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2016</year>
+ <year>2005</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -44,8 +44,7 @@
<item><p><c>"sftp"</c></p></item>
<tag><c>channel_callback() =</c></tag>
<item><p><c>atom()</c> - Name of the Erlang module implementing the subsystem using the
- <c>ssh_channel</c> behavior, see the
- <seealso marker="ssh_channel">ssh_channel(3)</seealso> manual page.</p></item>
+ <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>
diff --git a/lib/ssh/doc/src/terminology.xml b/lib/ssh/doc/src/terminology.xml
new file mode 100644
index 0000000000..db1e08970d
--- /dev/null
+++ b/lib/ssh/doc/src/terminology.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2018</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>Terminology</title>
+ <prepared></prepared>
+ <docno></docno>
+ <approved></approved>
+ <date></date>
+ <rev></rev>
+ <file>terminology.xml</file>
+ </header>
+
+ <section>
+ <title>General Information</title>
+ <p>In the following terms that may cause confusion are explained.
+ </p>
+ </section>
+
+ <section>
+ <title>The term "user"</title>
+ <p>A "user" is a term that everyone understands intuitively. However, the understandings may differ which can
+ cause confusion.
+ </p>
+ <p>The term is used differently in <url href="http://www.openssh.com">OpenSSH</url> and SSH in Erlang/OTP.
+ The reason is the different environments and use cases that are not immediatly obvious.
+ </p>
+ <p>This chapter aims at explaining the differences and giving a rationale for why Erlang/OTP handles "user" as
+ it does.
+ </p>
+
+ <section>
+ <title>In OpenSSH</title>
+ <p>Many have been in contact with the command 'ssh' on a Linux machine (or similar) to remotly log in on
+ another machine. One types
+ </p>
+ <code>ssh host</code>
+ <p>to log in on the machine named <c>host</c>. The command prompts for your password on the remote <c>host</c> and
+ then you can read, write and execute as your <i>user name</i> has rights on the remote <c>host</c>. There are
+ stronger variants with pre-distributed keys or certificates, but that are for now just details in the
+ authentication process.
+ </p>
+ <p>You could log in as the user <c>anotheruser</c> with
+ </p>
+ <code>ssh anotheruser@host</code>
+ <p>and you will then be enabled to act as <c>anotheruser</c> on the <c>host</c> if authorized correctly.
+ </p>
+ <p>So what does <i>"your user name has rights"</i> mean? In a UNIX/Linux/etc context it is exactly as that context:
+ The <i>user</i> could read, write and execute programs according to the OS rules.
+ In addition, the user has a home directory (<c>$HOME</c>) and there is a <c>$HOME/.ssh/</c> directory
+ with ssh-specific files.
+ </p>
+ <section>
+ <title>SSH password authentication</title>
+ <p>When SSH tries to log in to a host, the ssh protocol communicates the user name (as a string) and a password.
+ The remote ssh server checks that there is such a user defined and that the provided password is acceptable.
+ </p>
+ <p>If so, the user is authorized.
+ </p>
+ </section>
+ <section>
+ <title>SSH public key authentication</title>
+ <p>This is a stronger method where the ssh protocol brings the user name, the user's public key and some
+ cryptographic information which we could ignore here.
+ </p>
+ <p>The ssh server on the remote host checks:
+ </p>
+ <list>
+ <item>That the <i>user</i> has a home directory,</item>
+ <item>that home directory contains a .ssh/ directory and</item>
+ <item>the .ssh/ directory contains the public key just received in the <c>authorized_keys</c> file</item>
+ </list>
+ <p>if so, the user is authorized.
+ </p>
+ </section>
+ <section>
+ <title>The SSH server on UNIX/Linux/etc after a succesful authentication</title>
+ <p>After a succesful incoming authentication, a new process runs as the just authenticated user.</p>
+ <p>Next step is to start a service according to the ssh request. In case of a request of a shell,
+ a new one is started which handles the OS-commands that arrives from the client (that's "you").
+ </p>
+ <p>In case of a sftp request, an sftp server is started in with the user's rights. So it could read, write or delete
+ files if allowed for that user.
+ </p>
+ </section>
+ </section>
+
+ <section>
+ <title>In Erlang/OTP SSH</title>
+ <p>For the Erlang/OTP SSH server the situation is different. The server executes in an Erlang process
+ in the Erlang emulator which in turn executes in an OS process. The emulator does not try to change its
+ user when authenticated over the SSH protocol.
+ So the remote user name is only for authentication purposes in the Erlang/OTP SSH application.
+ </p>
+ <section>
+ <title>Password authentication in Erlang SSH</title>
+ <p>The Erlang/OTP SSH server checks the user name and password in the following order:
+ </p>
+ <list type="ordered">
+ <item>If a
+ <seealso marker="ssh:ssh#option-pwdfun"><c>pwdfun</c></seealso>
+ is defined, that one is called and the returned boolean is the authentication result.
+ </item>
+ <item>Else, if the
+ <seealso marker="ssh:ssh#option-user_passwords"><c>user_passwords</c></seealso>
+ option is defined and the username and the password matches, the authentication is a success.
+ </item>
+ <item>Else, if the option
+ <seealso marker="ssh:ssh#option-password"><c>password</c></seealso>
+ is defined and matches the password the authentication is a success.
+ Note that the use of this option is not recommended in non-test code.
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>Public key authentication in Erlang SSH</title>
+ <p>The user name, public key and cryptographic data (a signature) that is sent by the client, are used as follows
+ (some steps left out for clearity):
+ </p>
+ <list type="ordered">
+ <item>A callback module is selected using the options
+ <seealso marker="ssh:ssh#type-key_cb_common_option"><c>key_cb</c></seealso>.
+ </item>
+ <item>The callback module is used to check that the provided public key is one of the user's pre-stored.
+ In case of the default callback module, the files <c>authorized_keys</c> and <c>authorized_keys2</c>
+ are searched in a directory found in the following order:
+ <list>
+ <item>If the option
+ <seealso marker="ssh:ssh_file#type-user_dir_fun_common_option"><c>user_dir_fun</c></seealso>
+ is defined, that fun is called and the returned directory is used,
+ </item>
+ <item>Else, If the option
+ <seealso marker="ssh:ssh_file#type-user_dir_common_option"><c>user_dir</c></seealso>
+ is defined, that directory is used,
+ </item>
+ <item>Else the subdirectory <c>.ssh</c> in the home directory of the user executing
+ the OS process of the Erlang emulator is used.
+ </item>
+ </list>
+ If the provided public key is not found, the authentication fails.
+ </item>
+ <item>Finally, if the provided public key is found, the signature provided by the client is checked with
+ the public key.
+ </item>
+ </list>
+ </section>
+ <section>
+ <title>The Erlang/OTP SSH server after a succesful authentication</title>
+ <p>After a successful authentication an <i>Erlang process</i> is handling the service request from the remote
+ ssh client. The rights of that process are those of the user of the OS process running the Erlang emulator.
+ </p>
+ <p>If a shell service request arrives to the server, an <i>Erlang shell</i> is opened in the server's emulator.
+ The rights in that shell is independent of the just authenticated user.
+ </p>
+ <p>In case of an sftp request, an sftp server is started with the rights of the user of the Erlang emulator's OS
+ process. So with sftp the authenticated user does not influence the rights.
+ </p>
+ <p>So after an authentication, the user name is not used anymore and has no influence.
+ </p>
+ </section>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/ssh/doc/src/usersguide.xml b/lib/ssh/doc/src/usersguide.xml
index 70051ba771..8a4df208d8 100644
--- a/lib/ssh/doc/src/usersguide.xml
+++ b/lib/ssh/doc/src/usersguide.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2012</year><year>2016</year>
+ <year>2012</year><year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -36,4 +36,6 @@
</description>
<xi:include href="introduction.xml"/>
<xi:include href="using_ssh.xml"/>
+ <xi:include href="terminology.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 0861c641c7..4455d5ecc5 100644
--- a/lib/ssh/doc/src/using_ssh.xml
+++ b/lib/ssh/doc/src/using_ssh.xml
@@ -5,7 +5,7 @@
<header>
<copyright>
<year>2012</year>
- <year>2016</year>
+ <year>2018</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -74,16 +74,17 @@
<marker id="Running an Erlang ssh Daemon"></marker>
<title>Running an Erlang ssh Daemon</title>
- <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>The
+ <seealso marker="ssh_file#type-system_dir_daemon_option"><c>system_dir</c></seealso>
+ 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 <c>/etc/ssh</c> directory is only readable by root.</p>
</note>
- <p>The option <c>user_dir</c> defaults to directory <c>users ~/.ssh</c>.</p>
+ <p>The option <seealso marker="ssh_file#type-user_dir_common_option"><c>user_dir</c></seealso>
+ defaults to directory <c>users ~/.ssh</c>.</p>
<p><em>Step 1.</em> To run the example without root privileges,
generate new keys and host keys:</p>
@@ -298,6 +299,7 @@ ok = erl_tar:close(HandleRead),
</section>
<section>
+ <marker id="usersguide_creating_a_subsystem"/>
<title>Creating a Subsystem</title>
<p>A small <c>ssh</c> subsystem that echoes N bytes can be implemented as shown
@@ -305,7 +307,7 @@ ok = erl_tar:close(HandleRead),
<code type="erl" >
-module(ssh_echo_server).
--behaviour(ssh_subsystem).
+-behaviour(ssh_server_channel). % replaces ssh_daemon_channel
-record(state, {
n,
id,
@@ -383,7 +385,7 @@ terminate(_Reason, _State) ->
{ssh_msg, &lt;0.57.0>, {closed, 0}}
7> {error, closed} = ssh_connection:send(ConnectionRef, ChannelId, "10", infinity).
</code>
-<p>See also <seealso marker="ssh_channel"> ssh_channel(3)</seealso>.</p>
+<p>See also <seealso marker="ssh_client_channel">ssh_client_channel(3)</seealso> (replaces ssh_channel(3)).</p>
</section>