1
1
libssh/doc/tutorial.dox
2010-08-19 15:06:38 +02:00

844 строки
29 KiB
Plaintext

/**
* @page tutorial The Tutorial
*
* @section introduction Introduction
*
* libssh is a C library that enables you to write a program that uses the
* SSH protocol. With it, you can remotely execute programs, transfer
* files, or use a secure and transparent tunnel for your remote programs.
* The SSH protocol is encrypted, ensures data integrity, and provides strong
* means of authenticating both the server of the client. The library hides
* a lot of technical details from the SSH protocol, but this does not
* mean that you should not try to know about and understand these details.
*
* libssh is a Free Software / Open Source project. The libssh library
* is distributed under LGPL license. The libssh project has nothing to do with
* "libssh2", which is a completly different and independant project.
*
* libssh supports both client and server sides of the SSH protocol.
* The following document explains how to set up a client-side connection.
* If you are going to program a server, you should try first to code some
* client-side programs in order to understand how libssh works.
*
* This tutorial describes libssh version 0.5.0.
*
*
* Table of contents:
*
* @subpage session
*
* @subpage details
*
* @subpage tbd
*
*
* @page session Chapter 1: A typical SSH session
* @section ssh_session A typical SSH session
*
* A SSH session goes through the following steps:
*
* - Before connecting to the server, you can set up if you wish one or other
* server public key authentication, i.e. DSA or RSA. You can choose
* cryptographic algorithms you trust and compression algorithms if any. You
* must of course set up the hostname.
*
* - The connection is established. A secure handshake is made, and resulting from
* it, a public key from the server is gained. You MUST verify that the public
* key is legitimate, using for instance the MD5 fingerprint or the known hosts
* file.
*
* - The client must authenticate: the classical ways are password, or
* public keys (from dsa and rsa key-pairs generated by openssh).
* If a SSH agent is running, it is possible to use it.
*
* - Now that the user has been authenticated, you must open one or several
* channels. Channels are different subways for information into a single ssh
* connection. Each channel has a standard stream (stdout) and an error stream
* (stderr). You can theoretically open an infinity of channels.
*
* - With the channel you opened, you can do several things:
* - Execute a single command.
* - Open a shell. You may want to request a pseudo virtual terminal before.
* - Invoke the sftp subsystem to transfer files.
* - Invoke the scp subsystem to transfer files.
* - Invoke your own subsystem. This is outside the scope of this document,
* but it is easy to do.
*
* - When everything is finished, just close the channels, and then the connection.
*
* All the libssh functions which return an error code also set an error message.
* Error codes are typically SSH_ERROR for integer values, or NULL for pointers.
*
*
* @subsection setup Creating the session and setting options
*
* The most important object in a SSH connection is the SSH session. In order
* to allocate a new SSH session, you use ssh_new(). Don't forget to
* always verify that the allocation successed.
* @code
* #include <libssh/libssh.h>
* #include <stdlib.h>
*
* int main()
* {
* ssh_session my_ssh_session = ssh_new();
* if (my_ssh_session == NULL)
* exit(-1);
* ...
* ssh_free(my_ssh_session);
* }
* @endcode
*
* libssh follows the allocate-it-deallocate-it pattern. Each object that you allocate
* using xxxxx_new() must be deallocated using xxxxx_free(). In this case, ssh_new()
* does the allocation and ssh_free() does the contrary.
*
* The ssh_options_set() function sets the options of the session. The most important options are:
* - SSH_OPTIONS_HOST: the name of the host you want to connect to
* - SSH_OPTIONS_PORT: the used port (default is port 22)
* - SSH_OPTIONS_USER: the system user under which you want to connect
* - SSH_OPTIONS_LOG_VERBOSITY: the quantity of messages that are printed
*
* The complete list of options can be found in the documentation of ssh_options_set().
* The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
* the local username of your account will be used.
*
* Here is a small example of how to use it:
* @code
* #include <libssh/libssh.h>
* #include <stdlib.h>
*
* int main()
* {
* ssh_session my_ssh_session;
* int verbosity = SSH_LOG_PROTOCOL;
* int port = 22;
*
* my_ssh_session = ssh_new();
* if (my_ssh_session == NULL)
* exit(-1);
*
* ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
* ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
* ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
*
* ...
*
* ssh_free(my_ssh_session);
* }
* @endcode
*
* Please notice that all parameters are passed to ssh_options_set() as pointers,
* even if you need to set an integer value.
*
* @see ssh_new
* @see ssh_free
* @see ssh_options_set
* @see ssh_options_parse_config
* @see ssh_options_copy
* @see ssh_options_getopt
*
*
* @subsection connect Connecting to the server
*
* Once all settings have been made, you can connect using ssh_connect(). That
* function will return SSH_OK if the connection worked, SSH_ERROR otherwise.
*
* You can get the error string using ssh_get_error() in order to show the
* user what went wrong. Then, use ssh_disconnect() when you want to stop
* the session.
*
* Here's an example:
*
* @code
* #include <libssh/libssh.h>
* #include <stdlib.h>
* #include <stdio.h>
*
* int main()
* {
* ssh_session my_ssh_session;
* int ret;
*
* my_ssh_session = ssh_new();
* if (my_ssh_session == NULL)
* exit(-1);
*
* ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
*
* ret = ssh_connect(my_ssh_session);
* if (ret != SSH_OK)
* {
* fprintf(stderr, "Error connecting to localhost: %s\n",
* ssh_get_error(my_ssh_session));
* exit(-1);
* }
*
* ...
*
* ssh_disconnect(my_ssh_session);
* ssh_free(my_ssh_session);
* }
* @endcode
*
*
* @subsection serverauth Authenticating the server
*
* Once you're connected, the following step is mandatory: you must check that the server
* you just connected to is known and safe to use (remember, SSH is about security and
* authentication).
*
* There are two ways of doing this:
* - The first way (recommended) is to use the ssh_is_server_known()
* function. This function will look into the known host file
* (~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
* and determine whether this host is present or not in the list.
* - The second way is to use ssh_get_pubkey_hash() to get a binary version
* of the public key hash value. You can then use your own database to check
* if this public key is known and secure.
*
* You can also use the ssh_get_pubkey_hash() to show the public key hash
* value to the user, in case he knows what the public key hash value is
* (some paranoid people write their public key hash values on paper before
* going abroad, just in case ...).
*
* If the remote host is being used to for the first time, you can ask the user whether
* he/she trusts it. Once he/she concluded that the host is valid and worth being
* added in the known hosts file, you use ssh_write_knownhost() to register it in
* the known hosts file, or any other way if you use your own database.
*
* The following example is part of the examples suite available in the
* examples/ directory:
*
* @code
* int verify_knownhost(ssh_session session)
* {
* int state, hlen;
* unsigned char *hash = NULL;
* char *hexa;
* char buf[10];
*
* state = ssh_is_server_known(session);
*
* hlen = ssh_get_pubkey_hash(session, &hash);
* if (hlen < 0)
* return -1;
*
* switch (state)
* {
* case SSH_SERVER_KNOWN_OK:
* break; /* ok */
*
* case SSH_SERVER_KNOWN_CHANGED:
* fprintf(stderr, "Host key for server changed: it is now:\n");
* ssh_print_hexa("Public key hash", hash, hlen);
* fprintf(stderr, "For security reasons, connection will be stopped\n");
* free(hash);
* return -1;
*
* case SSH_SERVER_FOUND_OTHER:
* fprintf(stderr, "The host key for this server was not found but an other"
* "type of key exists.\n");
* fprintf(stderr, "An attacker might change the default server key to"
* "confuse your client into thinking the key does not exist\n"
* free(hash);
* return -1;
*
* case SSH_SERVER_FILE_NOT_FOUND:
* fprintf(stderr, "Could not find known host file.\n");
* fprintf(stderr, "If you accept the host key here, the file will be"
* "automatically created.\n");
* /* fallback to SSH_SERVER_NOT_KNOWN behavior */
*
* case SSH_SERVER_NOT_KNOWN:
* hexa = ssh_get_hexa(hash, hlen);
* fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
* fprintf(stderr, "Public key hash: %s\n", hexa);
* free(hexa);
* if (fgets(buf, sizeof(buf), stdin) == NULL)
* {
* free(hash);
* return -1;
* }
* if (strncasecmp(buf, "yes", 3) != 0)
* {
* free(hash);
* return -1;
* }
* if (ssh_write_knownhost(session) < 0)
* {
* fprintf(stderr, "Error %s\n", strerror(errno));
* free(hash);
* return -1;
* }
* break;
*
* case SSH_SERVER_ERROR:
* fprintf(stderr, "Error %s", ssh_get_error(session));
* free(hash);
* return -1;
* }
*
* free(hash);
* return 0;
* }
* @endcode
*
* @see ssh_connect
* @see ssh_disconnect
* @see ssh_get_error
* @see ssh_get_error_code
* @see ssh_get_pubkey_hash
* @see ssh_is_server_known
* @see ssh_write_knownhost
*
*
* @subsection auth Authenticating yourself
*
* The authentication process is the way a service provider can identify a
* user and verify his/her identity. The authorization process is about enabling
* the authenticated user the access to ressources. In SSH, the two concepts
* are linked. After authentication, the server can grant the user access to
* several ressources such as port forwarding, shell, sftp subsystem, and so on.
*
* libssh supports several methods of authentication:
* - "none" method. This method allows to get the available authentications
* methods. It also gives the server a chance to authenticate the user with
* just his/her login. Some very old hardware uses this feature to fallback
* the user on a "telnet over SSH" style of login.
* - password method. A password is sent to the server, which accepts it or not.
* - keyboard-interactive method. The server sends several challenges to the
* user, who must answer correctly. This makes possible the authentication
* via a codebook for instance ("give code at 23:R on page 3").
* - public key method. The host knows the public key of the user, and the
* user must prove he knows the associated private key. This can be done
* manually, or delegated to the SSH agent as we'll see later.
*
* All these methods can be combined. You can for instance force the user to
* authenticate with at least two of the authentication methods. In that case,
* one speaks of "Partial authentication". A partial authentication is a
* response from authentication functions stating that your credential was
* accepted, but yet another one is required to get in.
*
* The example below shows an authentication with password:
*
* @code
* #include <libssh/libssh.h>
* #include <stdlib.h>
* #include <stdio.h>
*
* int main()
* {
* ssh_session my_ssh_session;
* int ret;
* char *password;
*
* // Open session and set options
* my_ssh_session = ssh_new();
* if (my_ssh_session == NULL)
* exit(-1);
* ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
*
* // Connect to server
* ret = ssh_connect(my_ssh_session);
* if (ret != SSH_OK)
* {
* fprintf(stderr, "Error connecting to localhost: %s\n",
* ssh_get_error(my_ssh_session));
* ssh_free(my_ssh_session);
* exit(-1);
* }
*
* // Verify the server's identity
* // For the source code of verify_knowhost(), check previous example
* if (verify_knownhost(my_ssh_session) < 0)
* {
* ssh_disconnect(my_ssh_session);
* ssh_free(my_ssh_session);
* exit(-1);
* }
*
* // Authenticate ourselves
* password = getpass("Password: ");
* ret = ssh_userauth_password(my_ssh_session, NULL, password);
* if (ret != SSH_AUTH_SUCCESS)
* {
* fprintf(stderr, "Error authenticating with password: %s\n",
* ssh_get_error(my_ssh_session));
* ssh_disconnect(my_ssh_session);
* ssh_free(my_ssh_session);
* exit(-1);
* }
*
* ...
*
* ssh_disconnect(my_ssh_session);
* ssh_free(my_ssh_session);
* }
* @endcode
*
* @see @ref authentication_details
*
*
* @subsection using_ssh Doing something
*
* At this point, the authenticity of both server and client is established.
* Time has come to take advantage of the many possibilities offered by the SSH
* protocol: execute remote commands, open remote shells, transfer files,
* forward ports, etc.
*
* The example below puts the final touch to our step-by-step discovery
* of a SSH connection:
*
* @code
* /* *** To be replaced with something simpler *** */
* #include <sys/stat.h>
*
* int scp_helloworld(ssh_session session)
* {
* ssh_scp scp_session;
* int ret;
* const char *helloworld = "Hello, world!\n";
* int length = strlen(helloworld);
*
* // Open a scp session
* scp_session = ssh_scp_new
* (session, SSH_SCP_WRITE | SSH_SCP_RECURSIVE, ".");
* if (scp_session == NULL)
* {
* fprintf(stderr, "Error allocating scp session.\n");
* return SSH_ERROR;
* }
*
* // Initialize the scp session
* ret = ssh_scp_init(scp_session);
* if (ret != SSH_OK)
* {
* fprintf(stderr, "Error initializing scp session.\n");
* ssh_scp_free(scp_session);
* return ret;
* }
*
* // Open the remote file
* ret = ssh_scp_push_file
* (scp_session, "helloworld.txt", length, S_IRUSR | S_IWUSR);
* if (ret != SSH_OK)
* {
* fprintf(stderr, "Can't open remote file.\n");
* ssh_scp_close(scp_session);
* ssh_scp_free(scp_session);
* return ret;
* }
*
* // Write the data into the remote file
* ret = ssh_scp_write(scp_session, helloworld, length);
* if (ret != SSH_OK)
* {
* fprintf(stderr, "Can't write to remote file.\n");
* ssh_scp_close(scp_session);
* ssh_scp_free(scp_session);
* return ret;
* }
*
* ssh_scp_close(scp_session);
* ssh_scp_free(scp_session);
* return ret;
* }
* @endcode
*
* @see @ref opening_shell
* @see @ref remote_commands
* @see @ref sftp_subsystem
* @see @ref scp_subsystem
*
*
* @page details Chapter 2: A deeper insight on authentication
* @section authentication_details A deeper insight on authentication
*
*
* @subsection pubkeys Authenticating using public keys
*
* The public key authentication is the only method that does not compromise
* your key if the remote host has been compromised (the server can't do
* anything more than getting your public key). This is not the
* case of a password authentication (the server can get your plaintext
* password). On the other hand, if the client machine is compromised and
* the private key has no passphrase, then the attacker has gained automatic
* access to your server. It is not the purpose of this document to do
* a detailed review of the advantages and drawbacks of each authentication
* method, so refer to the abundant documentation on this topic on the
* Internet to fully understand the advantages and risks linked to each method.
*
* libssh is fully compatible with the openssh public and private keys. You
* can either use the automatic public key authentication method provided by
* libssh, or roll your own using the public key functions.
*
* The process of authenticating by public key to a server is the following:
* - you scan a list of files that contain public keys. each key is sent to
* the SSH server, until the server acknowledges a key (a key it knows can be
* used to authenticate the user).
* - then, you retrieve the private key for this key and send a message
* proving that you know that private key.
*
* The function ssh_userauth_autopubkey() does this using the available keys in
* "~/.ssh/". The return values are the following:
* - SSH_AUTH_ERROR: some serious error happened during authentication
* - SSH_AUTH_DENIED: no key matched
* - SSH_AUTH_SUCCESS: you are now authenticated
* - SSH_AUTH_PARTIAL: some key matched but you still have to provide an other
* mean of authentication (like a password).
*
* The ssh_userauth_autopubkey function also tries to authenticate using the
* SSH agent, if you have one running, or the "none" method otherwise.
*
* If you wish to authenticate with public key by your own, follow these steps:
* - Retrieve the public key in a ssh_string using publickey_from_file().
* - Offer the public key to the SSH server using ssh_userauth_offer_pubkey().
* If the return value is SSH_AUTH_SUCCESS, the SSH server accepts to
* authenticate using the public key and you can go to the next step.
* - Retrieve the private key, using the privatekey_from_file() function. If
* a passphrase is needed, either the passphrase specified as argument or
* a callback (see callbacks section) will be used.
* - Authenticate using ssh_userauth_pubkey() with your public key string
* and private key.
* - Do not forget cleaning up memory using string_free() and privatekey_free().
*
* Here is a minimalistic example of public key authentication:
*
* @code
* int authenticate_pubkey(ssh_session session)
* {
* int rc;
*
* rc = ssh_userauth_autopubkey(session, NULL);
*
* if (rc == SSH_AUTH_ERROR)
* {
* fprintf(stderr, "Authentication failed: %s\n",
* ssh_get_error(session));
* return SSH_AUTH_ERROR;
* }
*
* return rc;
* }
* @endcode
*
* @see ssh_userauth_autopubkey
* @see ssh_userauth_offer_pubkey
* @see ssh_userauth_pubkey
* @see publickey_from_file
* @see publickey_from_privatekey
* @see string_free
* @see privatekey_from_file
* @see privatekey_free
*
*
* @subsection password Authenticating using a password
*
* The function ssh_userauth_password() serves the purpose of authenticating
* using a password. It will return SSH_AUTH_SUCCESS if the password worked,
* or one of other constants otherwise. It's your work to ask the password
* and to deallocate it in a secure manner.
*
* If your server complains that the password is wrong, but you can still
* authenticate using openssh's client (issuing password), it's probably
* because openssh only accept keyboard-interactive. Switch to
* keyboard-interactive authentication, or try to configure plain text passwords
* on the SSH server.
*
* Here is a small example of password authentication:
*
* @code
* int authenticate_password(ssh_session session)
* {
* char *password;
* int rc;
*
* password = getpass("Enter your password: ");
* rc = ssh_userauth_password(session, NULL, password);
* if (rc == SSH_AUTH_ERROR)
* {
* fprintf(stderr, "Authentication failed: %s\n",
* ssh_get_error(session));
* return SSH_AUTH_ERROR;
* }
*
* return rc;
* }
* @endcode
*
* @see ssh_userauth_password
*
*
* @subsection keyb_int The keyboard-interactive authentication method
*
* The keyboard-interactive method is, as its name tells, interactive. The
* server will issue one or more challenges that the user has to answer,
* until the server takes an authentication decision.
*
* ssh_userauth_kbdint() is the the main keyboard-interactive function.
* It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
* SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
*
* The keyboard-interactive authentication method of SSH2 is a feature that
* permits the server to ask a certain number of questions in an interactive
* manner to the client, until it decides to accept or deny the login.
*
* To begin, you call ssh_userauth_kbdint() (just set user and submethods to
* NULL) and store the answer.
*
* If the answer is SSH_AUTH_INFO, it means that the server has sent a few
* questions that you should ask the user. You can retrieve these questions
* with the following functions: ssh_userauth_kbdint_getnprompts(),
* ssh_userauth_kbdint_getname(), ssh_userauth_kbdint_getinstruction(), and
* ssh_userauth_kbdint_getprompt().
*
* Set the answer for each question in the challenge using
* ssh_userauth_kbdint_setanswer().
*
* Then, call again ssh_userauth_kbdint() and start the process again until
* these functions returns something else than SSH_AUTH_INFO.
*
* Here are a few remarks:
* - Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
* - The server can send an empty question set (this is the default behavior
* on my system) after you have sent the answers to the first questions.
* You must still parse the answer, it might contain some
* message from the server saying hello or such things. Just call
* ssh_userauth_kbdint() until needed.
* - The meaning of "name", "prompt", "instruction" may be a little
* confusing. An explanation is given in the RFC section that follows.
*
* Here is a little note about how to use the information from
* keyboard-interactive authentication, coming from the RFC itself (rfc4256):
*
* @verbatim
*
* 3.3 User Interface Upon receiving a request message, the client SHOULD
* prompt the user as follows: A command line interface (CLI) client SHOULD
* print the name and instruction (if non-empty), adding newlines. Then for
* each prompt in turn, the client SHOULD display the prompt and read the
* user input.
*
* A graphical user interface (GUI) client has many choices on how to prompt
* the user. One possibility is to use the name field (possibly prefixed
* with the application's name) as the title of a dialog window in which
* the prompt(s) are presented. In that dialog window, the instruction field
* would be a text message, and the prompts would be labels for text entry
* fields. All fields SHOULD be presented to the user, for example an
* implementation SHOULD NOT discard the name field because its windows lack
* titles; it SHOULD instead find another way to display this information. If
* prompts are presented in a dialog window, then the client SHOULD NOT
* present each prompt in a separate window.
*
* All clients MUST properly handle an instruction field with embedded
* newlines. They SHOULD also be able to display at least 30 characters for
* the name and prompts. If the server presents names or prompts longer than 30
* characters, the client MAY truncate these fields to the length it can
* display. If the client does truncate any fields, there MUST be an obvious
* indication that such truncation has occured.
*
* The instruction field SHOULD NOT be truncated. Clients SHOULD use control
* character filtering as discussed in [SSH-ARCH] to avoid attacks by
* including terminal control characters in the fields to be displayed.
*
* For each prompt, the corresponding echo field indicates whether or not
* the user input should be echoed as characters are typed. Clients SHOULD
* correctly echo/mask user input for each prompt independently of other
* prompts in the request message. If a client does not honor the echo field
* for whatever reason, then the client MUST err on the side of
* masking input. A GUI client might like to have a checkbox toggling
* echo/mask. Clients SHOULD NOT add any additional characters to the prompt
* such as ": " (colon-space); the server is responsible for supplying all
* text to be displayed to the user. Clients MUST also accept empty responses
* from the user and pass them on as empty strings.
* @endverbatim
*
* The following example shows how to perform keyboard-interactive authentication:
*
* @code
* int authenticate_kbdint(ssh_session session)
* {
* int rc;
*
* rc = ssh_userauth_kbdint(session, NULL, NULL);
* while (rc == SSH_AUTH_INFO)
* {
* const char *name, *instruction;
* int nprompts, iprompt;
*
* name = ssh_userauth_kbdint_getname(session);
* instruction = ssh_userauth_kbdint_getinstruction(session);
* nprompts = ssh_userauth_kbdint_getnprompts(session);
*
* if (strlen(name) > 0)
* printf("%s\n", name);
* if (strlen(instruction) > 0)
* printf("%s\n", instruction);
* for (iprompt = 0; iprompt < nprompts; iprompt++)
* {
* const char *prompt;
* char echo;
*
* prompt = ssh_userauth_kbdint_getprompt(session, iprompt, &echo);
* if (echo)
* {
* char buffer[128], *ptr;
*
* printf("%s", prompt);
* if (fgets(buffer, sizeof(buffer), stdin) == NULL)
* return SSH_AUTH_ERROR;
* buffer[sizeof(buffer) - 1] = '\0';
* if ((ptr = strchr(buffer, '\n')) != NULL)
* *ptr = '\0';
* if (ssh_userauth_kbdint_setanswer(session, iprompt, buffer) < 0)
* return SSH_AUTH_ERROR;
* memset(buffer, 0, strlen(buffer));
* }
* else
* {
* char *ptr;
*
* ptr = getpass(prompt);
* if (ssh_userauth_kbdint_setanswer(session, iprompt, ptr) < 0)
* return SSH_AUTH_ERROR;
* }
* }
* rc = ssh_userauth_kbdint(session, NULL, NULL);
* }
* return rc;
* }
* @endcode
*
* @see ssh_userauth_kbdint()
* @see ssh_userauth_kbdint_getnprompts
* @see ssh_userauth_kbdint_getname
* @see ssh_userauth_kbdint_getinstruction
* @see ssh_userauth_kbdint_getprompt
* @see ssh_userauth_kbdint_setanswer()
*
*
* @subsection none Authenticating with "none" method
*
* The primary purpose of the "none" method is to get authenticated **without**
* any credential. Don't do that, use one of the other authentication methods,
* unless you really want to grant anonymous access.
*
* If the account has no password, and if the server is configured to let you
* pass, ssh_userauth_none() might answer SSH_AUTH_SUCCESS.
*
* The following example shows how to perform "none" authentication:
*
* @code
* int authenticate_kbdint(ssh_session session)
* {
* int rc;
*
* rc = ssh_userauth_none(session, NULL, NULL);
* return rc;
* }
* @endcode
*
* @subsection auth_list Getting the list of supported authentications
*
* You are not meant to choose a given authentication method, you can
* let the server tell you which methods are available. Once you know them,
* you try them one after the other.
*
* The following example shows how to get the list of available authentication
* methods with ssh_userauth_list() and how to use the result:
*
* @code
* /* Marche pas sans ssh_userauth_none(), du moins en 0.4.2 */
* int test_several_auth_methods(ssh_session session)
* {
* int method, rc;
*
* method = ssh_userauth_list(session, NULL);
*
* if (method & SSH_AUTH_METHOD_NONE)
* { // For the source code of function authenticate_none(),
* // refer to the corresponding example
* rc = authenticate_none(session);
* if (rc == SSH_AUTH_SUCCESS) return rc;
* }
* if (method & SSH_AUTH_METHOD_PUBLICKEY)
* { // For the source code of function authenticate_pubkey(),
* // refer to the corresponding example
* rc = authenticate_pubkey(session);
* if (rc == SSH_AUTH_SUCCESS) return rc;
* }
* if (method & SSH_AUTH_METHOD_INTERACTIVE)
* { // For the source code of function authenticate_kbdint(),
* // refer to the corresponding example
* rc = authenticate_kbdint(session);
* if (rc == SSH_AUTH_SUCCESS) return rc;
* }
* if (method & SSH_AUTH_METHOD_PASSWORD)
* { // For the source code of function authenticate_password(),
* // refer to the corresponding example
* rc = authenticate_password(session);
* if (rc == SSH_AUTH_SUCCESS) return rc;
* }
* return SSH_AUTH_ERROR;
* }
* @endcode
*
*
* @subsection banner
*
* The SSH server might send a banner, which you can retrieve with
* ssh_get_issue_banner(), then display to the user.
*
* The following example shows how to retrieve and dispose the issue banner:
*
* @code
* /* Marche pas sans ssh_userauth_none(), du moins en 0.4.2 */
* int display_banner(ssh_session session)
* {
* int rc;
* char *banner;
*
* rc = ssh_userauth_none(session, NULL);
* if (rc == SSH_AUTH_ERROR)
* return rc;
*
* banner = ssh_get_issue_banner(session);
* if (banner)
* {
* printf("%s\n", banner);
* free(banner);
* }
*
* return rc;
* }
* @endcode
*
*
* @page tbd Chapter 3: To be done
* @section opening_shell Opening a shell
*
* *** To be written ***
*
* @section remote_commands Passing remote commands
*
* *** To be written ***
*
* @section sftp_subsystem The SFTP subsystem
*
* *** To be written ***
*
* @section scp_subsystem The SCP subsystem
*
* *** To be written ***
*
* @section threads Working with threads
*
* *** To be written ***
*
* @section forwarding_connections Forwarding connections
*
* *** To be written ***
*
*/