mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Improve doxygen documentation
Signed-off-by: Nikhil V <nikhilgreyshines@gmail.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
@@ -220,36 +220,41 @@ typedef struct ssh_callbacks_struct *ssh_callbacks;
|
||||
* @param user User that wants to authenticate
|
||||
* @param password Password used for authentication
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||
* @returns `SSH_AUTH_SUCCESS` Authentication is accepted.
|
||||
* @returns `SSH_AUTH_PARTIAL` Partial authentication, more authentication means
|
||||
* are needed.
|
||||
* @returns `SSH_AUTH_DENIED` Authentication failed.
|
||||
*/
|
||||
typedef int (*ssh_auth_password_callback) (ssh_session session, const char *user, const char *password,
|
||||
void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback. Tries to authenticates user with the "none" method
|
||||
* which is anonymous or passwordless.
|
||||
* @brief SSH authentication callback. Tries to authenticates user with the
|
||||
* "none" method which is anonymous or passwordless.
|
||||
* @param session Current session handler
|
||||
* @param user User that wants to authenticate
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||
* @returns `SSH_AUTH_SUCCESS` Authentication is accepted.
|
||||
* @returns `SSH_AUTH_PARTIAL` Partial authentication, more authentication means
|
||||
* are needed.
|
||||
* @returns `SSH_AUTH_DENIED` Authentication failed.
|
||||
*/
|
||||
typedef int (*ssh_auth_none_callback) (ssh_session session, const char *user, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback. Tries to authenticates user with the "gssapi-with-mic" method
|
||||
* @brief SSH authentication callback. Tries to authenticates user with the
|
||||
* "gssapi-with-mic" method
|
||||
* @param session Current session handler
|
||||
* @param user Username of the user (can be spoofed)
|
||||
* @param principal Authenticated principal of the user, including realm.
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||
* @warning Implementations should verify that parameter user matches in some way the principal.
|
||||
* user and principal can be different. Only the latter is guaranteed to be safe.
|
||||
* @returns `SSH_AUTH_SUCCESS` Authentication is accepted.
|
||||
* @returns `SSH_AUTH_PARTIAL` Partial authentication, more authentication means
|
||||
* are needed.
|
||||
* @returns `SSH_AUTH_DENIED` Authentication failed.
|
||||
* @warning Implementations should verify that parameter user matches in some
|
||||
* way the principal. user and principal can be different. Only the latter is
|
||||
* guaranteed to be safe.
|
||||
*/
|
||||
typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *user, const char *principal,
|
||||
void *userdata);
|
||||
@@ -259,18 +264,18 @@ typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *us
|
||||
* @param session Current session handler
|
||||
* @param user User that wants to authenticate
|
||||
* @param pubkey public key used for authentication
|
||||
* @param signature_state SSH_PUBLICKEY_STATE_NONE if the key is not signed (simple public key probe),
|
||||
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
|
||||
* replied with a SSH_AUTH_DENIED.
|
||||
* @param signature_state `SSH_PUBLICKEY_STATE_NONE` if the key is not signed
|
||||
* (simple public key probe), `SSH_PUBLICKEY_STATE_VALID` if the signature is
|
||||
* valid. Others values should be replied with a `SSH_AUTH_DENIED`.
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||
* @returns `SSH_AUTH_SUCCESS` Authentication is accepted.
|
||||
* @returns `SSH_AUTH_PARTIAL` Partial authentication, more authentication means
|
||||
* are needed.
|
||||
* @returns `SSH_AUTH_DENIED` Authentication failed.
|
||||
*/
|
||||
typedef int (*ssh_auth_pubkey_callback) (ssh_session session, const char *user, struct ssh_key_struct *pubkey,
|
||||
char signature_state, void *userdata);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handles an SSH service request
|
||||
* @param session current session handler
|
||||
@@ -291,7 +296,7 @@ typedef int (*ssh_service_request_callback) (ssh_session session, const char *se
|
||||
*/
|
||||
typedef ssh_channel (*ssh_channel_open_request_session_callback) (ssh_session session, void *userdata);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief handle the beginning of a GSSAPI authentication, server side.
|
||||
* Callback should select the oid and also acquire the server credential.
|
||||
* @param session current session handler
|
||||
@@ -312,23 +317,23 @@ typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const
|
||||
* @param[in] input_token input token provided by client
|
||||
* @param[out] output_token output of the gssapi accept_sec_context method,
|
||||
* NULL after completion.
|
||||
* @returns SSH_OK if the token was generated correctly or accept_sec_context
|
||||
* @returns `SSH_OK` if the token was generated correctly or accept_sec_context
|
||||
* returned GSS_S_COMPLETE
|
||||
* @returns SSH_ERROR in case of error
|
||||
* @returns `SSH_ERROR` in case of error
|
||||
* @warning It is not necessary to fill this callback in if libssh is linked
|
||||
* with libgssapi.
|
||||
*/
|
||||
typedef int (*ssh_gssapi_accept_sec_ctx_callback) (ssh_session session,
|
||||
ssh_string input_token, ssh_string *output_token, void *userdata);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Verify and authenticates a MIC, server side.
|
||||
* @param session current session handler
|
||||
* @param[in] mic input mic to be verified provided by client
|
||||
* @param[in] mic_buffer buffer of data to be signed.
|
||||
* @param[in] mic_buffer_size size of mic_buffer
|
||||
* @returns SSH_OK if the MIC was authenticated correctly
|
||||
* @returns SSH_ERROR in case of error
|
||||
* @returns `SSH_OK` if the MIC was authenticated correctly
|
||||
* @returns `SSH_ERROR` in case of error
|
||||
* @warning It is not necessary to fill this callback in if libssh is linked
|
||||
* with libgssapi.
|
||||
*/
|
||||
@@ -404,7 +409,7 @@ struct ssh_server_callbacks_struct {
|
||||
/** This function will be called when a gssapi token comes in.
|
||||
*/
|
||||
ssh_gssapi_accept_sec_ctx_callback gssapi_accept_sec_ctx_function;
|
||||
/* This function will be called when a MIC needs to be verified.
|
||||
/** This function will be called when a MIC needs to be verified.
|
||||
*/
|
||||
ssh_gssapi_verify_mic_callback gssapi_verify_mic_function;
|
||||
/**
|
||||
@@ -438,7 +443,7 @@ typedef struct ssh_server_callbacks_struct *ssh_server_callbacks;
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_set_server_callbacks(ssh_session session, ssh_server_callbacks cb);
|
||||
|
||||
@@ -569,14 +574,17 @@ typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/** @brief Prototype for a packet callback, to be called when a new packet arrives
|
||||
/** @brief Prototype for a packet callback, to be called when a new packet
|
||||
* arrives
|
||||
* @param session The current session of the packet
|
||||
* @param type packet type (see ssh2.h)
|
||||
* @param packet buffer containing the packet, excluding size, type and padding fields
|
||||
* @param packet buffer containing the packet, excluding size, type and padding
|
||||
* fields
|
||||
* @param user user argument to the callback
|
||||
* and are called each time a packet shows up
|
||||
* @returns SSH_PACKET_USED Packet was parsed and used
|
||||
* @returns SSH_PACKET_NOT_USED Packet was not used or understood, processing must continue
|
||||
* @returns `SSH_PACKET_USED` Packet was parsed and used
|
||||
* @returns `SSH_PACKET_NOT_USED` Packet was not used or understood, processing
|
||||
* must continue
|
||||
*/
|
||||
typedef int (*ssh_packet_callback) (ssh_session session, uint8_t type, ssh_buffer packet, void *user);
|
||||
|
||||
@@ -635,7 +643,7 @@ typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
|
||||
|
||||
@@ -987,7 +995,7 @@ typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
* @warning this function will not replace existing callbacks but set the
|
||||
* new one atop of them.
|
||||
*/
|
||||
@@ -1006,7 +1014,7 @@ LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
|
||||
*
|
||||
* @param cb The callback structure itself.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*
|
||||
* @see ssh_set_channel_callbacks
|
||||
*/
|
||||
@@ -1023,7 +1031,7 @@ LIBSSH_API int ssh_add_channel_callbacks(ssh_channel channel,
|
||||
*
|
||||
* @param cb The callback structure to remove
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR on error.
|
||||
* @returns `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
|
||||
ssh_channel_callbacks cb);
|
||||
@@ -1056,7 +1064,7 @@ struct ssh_threads_callbacks_struct {
|
||||
* @param[in] cb A pointer to a ssh_threads_callbacks_struct structure, which
|
||||
* contains the different callbacks to be set.
|
||||
*
|
||||
* @returns Always returns SSH_OK.
|
||||
* @returns Always returns `SSH_OK`.
|
||||
*
|
||||
* @see ssh_threads_callbacks_struct
|
||||
* @see SSH_THREADS_PTHREAD
|
||||
|
||||
@@ -30,23 +30,27 @@
|
||||
*/
|
||||
|
||||
/** @internal
|
||||
* @brief Length of an ED25519 public key in bytes.
|
||||
* @brief ED25519 public key.
|
||||
* Ed25519 public key consist of 32 bytes.
|
||||
*/
|
||||
#define ED25519_PK_LEN 32
|
||||
|
||||
/** @internal
|
||||
* @brief Length of an ED25519 private key in bytes.
|
||||
* @brief ED25519 secret key.
|
||||
* Ed25519 secret key consist of 64 bytes.
|
||||
*/
|
||||
#define ED25519_SK_LEN 64
|
||||
|
||||
/** @internal
|
||||
* @brief Length of an ED25519 signature in bytes.
|
||||
* @brief ED25519 signature.
|
||||
* Ed25519 signatures consist of 64 bytes.
|
||||
*/
|
||||
#define ED25519_SIG_LEN 64
|
||||
|
||||
/** @internal
|
||||
* @brief ED25519 public key.
|
||||
* The public key consists of 32 bytes and can be used for key exchanges.
|
||||
* The public key consists of 32 bytes and can be used for signature
|
||||
* verification.
|
||||
*/
|
||||
typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
|
||||
|
||||
|
||||
@@ -455,44 +455,9 @@ enum ssh_connector_flags_e {
|
||||
SSH_CONNECTOR_BOTH = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Flushes the output buffer of the session, blocking until the buffer is empty or the timeout is reached
|
||||
*
|
||||
* @param[in] session The ssh session.
|
||||
* @param[in] timeout Timeout (milliseconds)
|
||||
*
|
||||
* @return SSH_OK on success (0), SSH_ERROR on error (-1).
|
||||
*/
|
||||
LIBSSH_API int ssh_blocking_flush(ssh_session session, int timeout);
|
||||
|
||||
/**
|
||||
* @brief Accept an X11 connection from the server.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] timeout_ms Timeout (milliseconds).
|
||||
*
|
||||
* @return A new X11 channel, or NULL on error.
|
||||
*/
|
||||
LIBSSH_API ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Change the size of the terminal .
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] cols Number of columns.
|
||||
* @param[in] rows Number of rows.
|
||||
*
|
||||
* @return SSH_OK on success (0), SSH_ERROR on error(-1).
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_change_pty_size(ssh_channel channel,int cols,int rows);
|
||||
|
||||
/**
|
||||
* @brief Closes a channel.
|
||||
*
|
||||
* @param[in] channel The channel.
|
||||
*
|
||||
* @return SSH_OK on success(0), SSH_ERROR on error(-1).
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_close(ssh_channel channel);
|
||||
#define SSH_CHANNEL_FREE(x) \
|
||||
do { \
|
||||
@@ -501,129 +466,23 @@ LIBSSH_API int ssh_channel_close(ssh_channel channel);
|
||||
(x) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @brief Frees a channel.
|
||||
*
|
||||
* @param[in] channel The channel.
|
||||
*/
|
||||
LIBSSH_API void ssh_channel_free(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Get the exit status of a channel .
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[out] pexit_code the exit code (can be NULL).
|
||||
* @param[out] pexit_signal the exit signal string (can be NULL).
|
||||
* @param[out] pcore_dumped the core dump flag (can be NULL).
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_get_exit_state(ssh_channel channel,
|
||||
uint32_t *pexit_code,
|
||||
char **pexit_signal,
|
||||
int *pcore_dumped);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Used to get the session .
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return The ssh session.
|
||||
*/
|
||||
LIBSSH_API ssh_session ssh_channel_get_session(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Check if the channel is closed.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return 1 if the channel is closed, 0 otherwise.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_is_closed(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Check if the remote host has sent an EOF (End Of File).
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return 1 if EOF has been received, 0 otherwise.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Check if the channel is open.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return 1 if the channel is open, 0 otherwise.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_is_open(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Create a new channel.
|
||||
*
|
||||
* @param[in] session The ssh session to use.
|
||||
*
|
||||
* @return a new channel, or NULL on error.
|
||||
*/
|
||||
LIBSSH_API ssh_channel ssh_channel_new(ssh_session session);
|
||||
|
||||
/**
|
||||
* @brief Open an authentication agent forwarding channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_open_auth_agent(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Open a TCP/IP forwarding channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] remotehost The remote host that connect to.
|
||||
* @param[in] remoteport The remote port that connect to.
|
||||
* @param[in] sourcehost The source host from which to connect.
|
||||
* @param[in] localport The source port from which to connect.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
|
||||
/**
|
||||
* @brief Open a Unix domain socket forwarding channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] remotepath The remote path of the socket.
|
||||
* @param[in] sourcehost The source host from which to connect.
|
||||
* @param[in] localport The source port from which to connect.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_open_forward_unix(ssh_channel channel, const char *remotepath,
|
||||
const char *sourcehost, int localport);
|
||||
|
||||
/**
|
||||
* @brief Open a session channel .
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_open_session(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Open an X11 channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] orig_addr The source address .
|
||||
* @param[in] orig_port The source port.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr, int orig_port);
|
||||
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr);
|
||||
@@ -631,287 +490,48 @@ LIBSSH_API int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count,
|
||||
LIBSSH_API int ssh_channel_read_timeout(ssh_channel channel, void *dest, uint32_t count, int is_stderr, int timeout_ms);
|
||||
LIBSSH_API int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr);
|
||||
|
||||
/**
|
||||
* @brief Set an environment variable on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] name The name of the variable.
|
||||
* @param[in] value The value to set.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Run a command on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] cmd The command to run.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
|
||||
|
||||
/**
|
||||
* @brief Request a PTY (pseudo-terminal) on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Request a PTY (pseudo-terminal) size on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] term The terminal type .
|
||||
* @param[in] cols The number of columns.
|
||||
* @param[in] rows The number of rows.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_pty_size(ssh_channel channel, const char *term,
|
||||
int cols, int rows);
|
||||
|
||||
/**
|
||||
* @brief Request a PTY (pseudo-terminal) size and modes on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] term The terminal type.
|
||||
* @param[in] cols The number of columns.
|
||||
* @param[in] rows The number of rows.
|
||||
* @param[in] modes The encoded terminal modes.
|
||||
* @param[in] modes_len The length of the modes data.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *term,
|
||||
int cols, int rows, const unsigned char* modes, size_t modes_len);
|
||||
|
||||
/**
|
||||
* @brief Request a shell on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_shell(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Send a signal to the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] signum The signal name .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_send_signal(ssh_channel channel, const char *signum);
|
||||
|
||||
/**
|
||||
* @brief Send a break signal to the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] length The length of the break in ms.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_send_break(ssh_channel channel, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Request the SFTP subsystem on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_sftp(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Request a subsystem on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] subsystem The subsystem name.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_subsystem(ssh_channel channel, const char *subsystem);
|
||||
LIBSSH_API int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
const char *cookie, int screen_number);
|
||||
|
||||
/**
|
||||
* @brief Request agent forwarding on the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_request_auth_agent(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Send EOF (End Of File) to the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Set the channel to blocking or non-blocking mode.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] blocking Set to 1 for blocking, 0 for non-blocking.
|
||||
*/
|
||||
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
|
||||
|
||||
/**
|
||||
* @brief Set the counter structure for the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] counter The counter to update.
|
||||
*/
|
||||
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
|
||||
ssh_counter counter);
|
||||
|
||||
/**
|
||||
* @brief Write data to the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] data The data to be written.
|
||||
* @param[in] len The length of the data.
|
||||
*
|
||||
* @return The number of bytes written, or SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Write data to the channel's standard error.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] data The data to be written.
|
||||
* @param[in] len The length of the data.
|
||||
*
|
||||
* @return The number of bytes written, or SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_write_stderr(ssh_channel channel,
|
||||
const void *data,
|
||||
uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Get the current window size of the channel.
|
||||
*
|
||||
* @param[in] channel The channel .
|
||||
*
|
||||
* @return The window size.
|
||||
*/
|
||||
LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel);
|
||||
|
||||
/**
|
||||
* @brief Get the file name from a path.
|
||||
*
|
||||
* @param[in] path The path.
|
||||
*
|
||||
* @return The base name, or NULL on error.
|
||||
*/
|
||||
LIBSSH_API char *ssh_basename (const char *path);
|
||||
|
||||
/**
|
||||
* @brief Clean up and free a public key hash.
|
||||
*
|
||||
* @param[in,out] hash The hash to free.
|
||||
*/
|
||||
LIBSSH_API void ssh_clean_pubkey_hash(unsigned char **hash);
|
||||
|
||||
/**
|
||||
* @brief Connects to the ssh server.
|
||||
*
|
||||
* @param[in] session The ssh session.
|
||||
*
|
||||
* @return SSH_OK on success (0), SSH_ERROR on error (-1).
|
||||
*/
|
||||
LIBSSH_API int ssh_connect(ssh_session session);
|
||||
|
||||
/**
|
||||
* @brief Create a new connector.
|
||||
*
|
||||
* @param[in] session The session .
|
||||
*
|
||||
* @return A new connector, or NULL on error.
|
||||
*/
|
||||
LIBSSH_API ssh_connector ssh_connector_new(ssh_session session);
|
||||
|
||||
/**
|
||||
* @brief Free a connector.
|
||||
*
|
||||
* @param[in] connector The connector to free.
|
||||
*/
|
||||
LIBSSH_API void ssh_connector_free(ssh_connector connector);
|
||||
|
||||
/**
|
||||
* @brief Set the input channel for the connector.
|
||||
*
|
||||
* @param[in] connector The connector .
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] flags Flags for the connector.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_connector_set_in_channel(ssh_connector connector,
|
||||
ssh_channel channel,
|
||||
enum ssh_connector_flags_e flags);
|
||||
|
||||
/**
|
||||
* @brief Set the output channel for the connector.
|
||||
*
|
||||
* @param[in] connector The connector .
|
||||
* @param[in] channel The channel .
|
||||
* @param[in] flags Flags for the connector.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_connector_set_out_channel(ssh_connector connector,
|
||||
ssh_channel channel,
|
||||
enum ssh_connector_flags_e flags);
|
||||
|
||||
/**
|
||||
* @brief Set the input file descriptor for the connector.
|
||||
*
|
||||
* @param[in] connector The connector .
|
||||
* @param[in] fd The file descriptor.
|
||||
*/
|
||||
LIBSSH_API void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd);
|
||||
|
||||
/**
|
||||
* @brief Set the output file descriptor for the connector.
|
||||
*
|
||||
* @param[in] connector The connector .
|
||||
* @param[in] fd The file descriptor.
|
||||
*/
|
||||
LIBSSH_API void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd);
|
||||
|
||||
/**
|
||||
* @brief Get the copyright information.
|
||||
*
|
||||
* @return The copyright string.
|
||||
*/
|
||||
LIBSSH_API const char *ssh_copyright(void);
|
||||
|
||||
/**
|
||||
* @brief Disconnects from the ssh server.
|
||||
*
|
||||
* @param[in] session The ssh session to be disconnected.
|
||||
*/
|
||||
LIBSSH_API void ssh_disconnect(ssh_session session);
|
||||
|
||||
/**
|
||||
* @brief Get the directory name from a path.
|
||||
*
|
||||
* @param[in] path The path.
|
||||
*
|
||||
* @return The directory name, or NULL on error.
|
||||
*/
|
||||
LIBSSH_API char *ssh_dirname (const char *path);
|
||||
LIBSSH_API int ssh_finalize(void);
|
||||
|
||||
@@ -924,16 +544,6 @@ LIBSSH_API ssh_channel ssh_channel_open_forward_port(ssh_session session,
|
||||
SSH_DEPRECATED LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
|
||||
int timeout_ms,
|
||||
int *destination_port);
|
||||
|
||||
/**
|
||||
* @brief Cancel a reverse port forwarding.
|
||||
*
|
||||
* @param[in] session The ssh session.
|
||||
* @param[in] address The address bound.
|
||||
* @param[in] port The port bound.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
|
||||
const char *address,
|
||||
int port);
|
||||
@@ -942,20 +552,7 @@ LIBSSH_API int ssh_channel_listen_forward(ssh_session session,
|
||||
int port,
|
||||
int *bound_port);
|
||||
|
||||
/**
|
||||
* @brief Free an ssh session.
|
||||
*
|
||||
* @param[in] session The session to free.
|
||||
*/
|
||||
LIBSSH_API void ssh_free(ssh_session session);
|
||||
|
||||
/**
|
||||
* @brief Get the disconnect message from the server.
|
||||
*
|
||||
* @param[in] session The ssh session.
|
||||
*
|
||||
* @return The disconnect message, or NULL if none.
|
||||
*/
|
||||
LIBSSH_API const char *ssh_get_disconnect_message(ssh_session session);
|
||||
LIBSSH_API const char *ssh_get_error(void *error);
|
||||
LIBSSH_API int ssh_get_error_code(void *error);
|
||||
|
||||
@@ -118,7 +118,7 @@ LIBSSH_API int ssh_bind_listen(ssh_bind ssh_bind_o);
|
||||
*
|
||||
* @param[in] userdata A pointer to private data to pass to the callbacks.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*
|
||||
* @code
|
||||
* struct ssh_callbacks_struct cb = {
|
||||
@@ -172,7 +172,7 @@ LIBSSH_API void ssh_bind_fd_toaccept(ssh_bind ssh_bind_o);
|
||||
* @param ssh_bind_o The ssh server bind to accept a connection.
|
||||
* @param session A preallocated ssh session
|
||||
* @see ssh_new
|
||||
* @return SSH_OK when a connection is established
|
||||
* @return `SSH_OK` when a connection is established
|
||||
*/
|
||||
LIBSSH_API int ssh_bind_accept(ssh_bind ssh_bind_o, ssh_session session);
|
||||
|
||||
@@ -186,7 +186,7 @@ LIBSSH_API int ssh_bind_accept(ssh_bind ssh_bind_o, ssh_session session);
|
||||
* inbound connection
|
||||
* @see ssh_new
|
||||
* @see ssh_bind_accept
|
||||
* @return SSH_OK when a connection is established
|
||||
* @return `SSH_OK` when a connection is established
|
||||
*/
|
||||
LIBSSH_API int ssh_bind_accept_fd(ssh_bind ssh_bind_o, ssh_session session,
|
||||
socket_t fd);
|
||||
@@ -198,7 +198,7 @@ LIBSSH_API ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session);
|
||||
*
|
||||
* @param session A connected ssh session
|
||||
* @see ssh_bind_accept
|
||||
* @return SSH_OK if the key exchange was successful
|
||||
* @return `SSH_OK` if the key exchange was successful
|
||||
*/
|
||||
LIBSSH_API int ssh_handle_key_exchange(ssh_session session);
|
||||
|
||||
@@ -215,9 +215,8 @@ LIBSSH_API int ssh_handle_key_exchange(ssh_session session);
|
||||
* @see ssh_handle_key_exchange
|
||||
* @see ssh_options_set
|
||||
*
|
||||
* @return SSH_OK if initialization succeeds.
|
||||
* @return `SSH_OK` if initialization succeeds.
|
||||
*/
|
||||
|
||||
LIBSSH_API int ssh_server_init_kex(ssh_session session);
|
||||
|
||||
/**
|
||||
@@ -257,7 +256,7 @@ LIBSSH_API void ssh_set_auth_methods(ssh_session session, int auth_methods);
|
||||
*
|
||||
* @param[in] banner The server's banner.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*/
|
||||
LIBSSH_API int ssh_send_issue_banner(ssh_session session, const ssh_string banner);
|
||||
|
||||
|
||||
248
src/channels.c
248
src/channels.c
@@ -321,7 +321,7 @@ static int ssh_channel_open_termination(void *c)
|
||||
*
|
||||
* @param[in] payload The buffer containing additional payload for the query.
|
||||
*
|
||||
* @return SSH_OK if successful; SSH_ERROR otherwise.
|
||||
* @return `SSH_OK` if successful; `SSH_ERROR` otherwise.
|
||||
*/
|
||||
static int
|
||||
channel_open(ssh_channel channel,
|
||||
@@ -433,7 +433,7 @@ ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id)
|
||||
* @brief grows the local window and sends a packet to the other party
|
||||
* @param session SSH session
|
||||
* @param channel SSH channel
|
||||
* @return SSH_OK if successful; SSH_ERROR otherwise.
|
||||
* @return `SSH_OK` if successful; `SSH_ERROR` otherwise.
|
||||
*/
|
||||
static int grow_window(ssh_session session,
|
||||
ssh_channel channel)
|
||||
@@ -1059,9 +1059,9 @@ int channel_default_bufferize(ssh_channel channel,
|
||||
*
|
||||
* @param[in] channel An allocated channel.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @see ssh_channel_open_forward()
|
||||
@@ -1084,15 +1084,15 @@ int ssh_channel_open_session(ssh_channel channel)
|
||||
|
||||
/**
|
||||
* @brief Open an agent authentication forwarding channel. This type of channel
|
||||
* can be opened by a server towards a client in order to provide SSH-Agent services
|
||||
* to the server-side process. This channel can only be opened if the client
|
||||
* claimed support by sending a channel request beforehand.
|
||||
* can be opened by a server towards a client in order to provide SSH-Agent
|
||||
* services to the server-side process. This channel can only be opened if the
|
||||
* client claimed support by sending a channel request beforehand.
|
||||
*
|
||||
* @param[in] channel An allocated channel.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @see ssh_channel_open_forward()
|
||||
@@ -1110,7 +1110,6 @@ int ssh_channel_open_auth_agent(ssh_channel channel)
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a TCP/IP forwarding channel.
|
||||
*
|
||||
@@ -1127,14 +1126,14 @@ int ssh_channel_open_auth_agent(ssh_channel channel)
|
||||
* @param[in] localport The port on the host from where the connection
|
||||
* originated. This is mostly for logging purposes.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @warning This function does not bind the local port and does not automatically
|
||||
* forward the content of a socket to the channel. You still have to
|
||||
* use ssh_channel_read and ssh_channel_write for this.
|
||||
* @warning This function does not bind the local port and does not
|
||||
* automatically forward the content of a socket to the channel. You still have
|
||||
* to use ssh_channel_read and ssh_channel_write for this.
|
||||
*/
|
||||
int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport)
|
||||
@@ -1199,16 +1198,16 @@ error:
|
||||
* @param[in] localport The port on the host from where the connection
|
||||
* originated. This is mostly for logging purposes.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK on` success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @warning This function does not bind the local port and does not
|
||||
* automatically forward the content of a socket to the channel.
|
||||
* You still have to use ssh_channel_read and ssh_channel_write for this.
|
||||
* automatically forward the content of a socket to the channel.
|
||||
* You still have to use ssh_channel_read and ssh_channel_write for this.
|
||||
* @warning Requires support of OpenSSH for UNIX domain socket forwarding.
|
||||
*/
|
||||
*/
|
||||
int ssh_channel_open_forward_unix(ssh_channel channel,
|
||||
const char *remotepath,
|
||||
const char *sourcehost,
|
||||
@@ -1359,7 +1358,7 @@ void ssh_channel_do_free(ssh_channel channel)
|
||||
*
|
||||
* @param[in] channel The channel to send the eof to.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*
|
||||
* Example:
|
||||
@code
|
||||
@@ -1436,7 +1435,7 @@ error:
|
||||
*
|
||||
* @param[in] channel The channel to close.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*
|
||||
* @see ssh_channel_free()
|
||||
* @see ssh_channel_is_eof()
|
||||
@@ -1524,11 +1523,11 @@ static int ssh_waitsession_unblocked(void *s)
|
||||
/**
|
||||
* @internal
|
||||
* @brief Flushes a channel (and its session) until the output buffer
|
||||
* is empty, or timeout elapsed.
|
||||
* is empty, or timeout elapsed.
|
||||
* @param channel SSH channel
|
||||
* @return SSH_OK On success,
|
||||
* SSH_ERROR On error.
|
||||
* SSH_AGAIN Timeout elapsed (or in nonblocking mode).
|
||||
* @return `SSH_OK` On success,
|
||||
* `SSH_ERROR` On error.
|
||||
* `SSH_AGAIN` Timeout elapsed (or in nonblocking mode).
|
||||
*/
|
||||
int ssh_channel_flush(ssh_channel channel)
|
||||
{
|
||||
@@ -1719,7 +1718,7 @@ uint32_t ssh_channel_window_size(ssh_channel channel)
|
||||
*
|
||||
* @param[in] len The length of the buffer to write to.
|
||||
*
|
||||
* @return The number of bytes written, SSH_ERROR on error.
|
||||
* @return The number of bytes written, `SSH_ERROR` on error.
|
||||
*
|
||||
* @see ssh_channel_read()
|
||||
*/
|
||||
@@ -1997,9 +1996,9 @@ error:
|
||||
*
|
||||
* @param[in] modes_len Number of bytes in 'modes'
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal,
|
||||
@@ -2055,6 +2054,19 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Request a PTY with a specific size using current TTY modes.
|
||||
*
|
||||
* Encodes @p terminal modes from the current TTY and sends a PTY request
|
||||
* for the given channel, terminal type, and size in columns/rows.
|
||||
*
|
||||
* @param[in] channel The channel to send the request on.
|
||||
* @param[in] terminal The terminal type (e.g. "xterm").
|
||||
* @param[in] col Number of columns.
|
||||
* @param[in] row Number of rows.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` on failure.
|
||||
*/
|
||||
int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
|
||||
int col, int row)
|
||||
{
|
||||
@@ -2077,9 +2089,9 @@ int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
|
||||
*
|
||||
* @param[in] channel The channel to send the request.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @see ssh_channel_request_pty_size()
|
||||
@@ -2098,7 +2110,7 @@ int ssh_channel_request_pty(ssh_channel channel)
|
||||
*
|
||||
* @param[in] rows The new number of rows.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*
|
||||
* @warning Do not call it from a signal handler if you are not sure any other
|
||||
* libssh function using the same channel/session is running at the
|
||||
@@ -2139,9 +2151,9 @@ error:
|
||||
*
|
||||
* @param[in] channel The channel to send the request.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_channel_request_shell(ssh_channel channel)
|
||||
@@ -2160,9 +2172,9 @@ int ssh_channel_request_shell(ssh_channel channel)
|
||||
*
|
||||
* @param[in] subsys The subsystem to request (for example "sftp").
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @warning You normally don't have to call it for sftp, see sftp_new().
|
||||
@@ -2210,9 +2222,9 @@ error:
|
||||
*
|
||||
* @param[in] channel The channel to request the sftp subsystem.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @note You should use sftp_new() which does this for you.
|
||||
@@ -2266,9 +2278,9 @@ static char *generate_cookie(void)
|
||||
*
|
||||
* @param[in] screen_number The screen number.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
@@ -2401,15 +2413,16 @@ ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an "auth-agent-req" channel request over an existing session channel.
|
||||
* @brief Send an "auth-agent-req" channel request over an existing session
|
||||
* channel.
|
||||
*
|
||||
* This client-side request will enable forwarding the agent over an secure tunnel.
|
||||
* When the server is ready to open one authentication agent channel, an
|
||||
* This client-side request will enable forwarding the agent over an secure
|
||||
* tunnel. When the server is ready to open one authentication agent channel, an
|
||||
* ssh_channel_open_request_auth_agent_callback event will be generated.
|
||||
*
|
||||
* @param[in] channel The channel to send signal.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred
|
||||
*/
|
||||
int ssh_channel_request_auth_agent(ssh_channel channel) {
|
||||
if (channel == NULL) {
|
||||
@@ -2490,9 +2503,9 @@ static int ssh_global_request_termination(void *s)
|
||||
*
|
||||
* @param[in] reply Set if you expect a reply from server.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_global_request(ssh_session session,
|
||||
@@ -2584,7 +2597,7 @@ error:
|
||||
|
||||
/**
|
||||
* @brief Sends the "tcpip-forward" global request to ask the server to begin
|
||||
* listening for inbound connections.
|
||||
* listening for inbound connections.
|
||||
*
|
||||
* @param[in] session The ssh session to send the request.
|
||||
*
|
||||
@@ -2599,9 +2612,9 @@ error:
|
||||
* @param[in] bound_port The pointer to get actual bound port. Pass NULL to
|
||||
* ignore.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
**/
|
||||
int ssh_channel_listen_forward(ssh_session session,
|
||||
@@ -2708,9 +2721,9 @@ ssh_channel ssh_channel_open_forward_port(ssh_session session, int timeout_ms, i
|
||||
*
|
||||
* @param[in] port The bound port on the server.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
int ssh_channel_cancel_forward(ssh_session session,
|
||||
@@ -2759,9 +2772,9 @@ int ssh_forward_cancel(ssh_session session, const char *address, int port)
|
||||
*
|
||||
* @param[in] value The value to set.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
* @warning Some environment variables may be refused by security reasons.
|
||||
*/
|
||||
@@ -2815,9 +2828,9 @@ error:
|
||||
* @param[in] cmd The command to execute
|
||||
* (e.g. "ls ~/ -al | grep -i reports").
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* Example:
|
||||
@@ -2880,9 +2893,9 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a signal to remote process (as described in RFC 4254, section 6.9).
|
||||
* @brief Send a signal to remote process (as described in RFC 4254,
|
||||
* section 6.9).
|
||||
*
|
||||
* Sends a signal 'sig' to the remote process.
|
||||
* Note, that remote system may not support signals concept.
|
||||
@@ -2906,7 +2919,7 @@ error:
|
||||
* SIGUSR1 -> USR1 \n
|
||||
* SIGUSR2 -> USR2 \n
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*/
|
||||
int ssh_channel_request_send_signal(ssh_channel channel, const char *sig)
|
||||
{
|
||||
@@ -2939,7 +2952,6 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a break signal to the server (as described in RFC 4335).
|
||||
*
|
||||
@@ -2951,7 +2963,7 @@ error:
|
||||
*
|
||||
* @param[in] length The break-length in milliseconds to send.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred
|
||||
*/
|
||||
int ssh_channel_request_send_break(ssh_channel channel, uint32_t length)
|
||||
{
|
||||
@@ -2989,13 +3001,14 @@ error:
|
||||
* @param[out] buffer The buffer which will get the data.
|
||||
*
|
||||
* @param[in] count The count of bytes to be read. If it is bigger than 0,
|
||||
* the exact size will be read, else (bytes=0) it will
|
||||
* return once anything is available.
|
||||
* the exact size will be read, else (bytes=0) it will return once anything is
|
||||
* available.
|
||||
*
|
||||
* @param is_stderr A boolean value to mark reading from the stderr stream.
|
||||
*
|
||||
* @return The number of bytes read, 0 on end of file, SSH_AGAIN on
|
||||
* timeout and SSH_ERROR on error.
|
||||
* @return The number of bytes read, 0 on end of file, `SSH_AGAIN`
|
||||
* on timeout and `SSH_ERROR` on error.
|
||||
*
|
||||
* @deprecated Please use ssh_channel_read instead
|
||||
* @warning This function doesn't work in nonblocking/timeout mode
|
||||
* @see ssh_channel_read
|
||||
@@ -3098,11 +3111,11 @@ static int ssh_channel_read_termination(void *s)
|
||||
*
|
||||
* @param[in] is_stderr A boolean value to mark reading from the stderr flow.
|
||||
*
|
||||
* @return The number of bytes read, 0 on end of file, SSH_AGAIN on
|
||||
* timeout and SSH_ERROR on error.
|
||||
* @return The number of bytes read, 0 on end of file, `SSH_AGAIN`
|
||||
* on timeout and `SSH_ERROR` on error.
|
||||
*
|
||||
* @warning This function may return less than count bytes of data, and won't
|
||||
* block until count bytes have been read.
|
||||
* block until count bytes have been read.
|
||||
*/
|
||||
int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr)
|
||||
{
|
||||
@@ -3127,8 +3140,8 @@ int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_std
|
||||
* @param[in] timeout_ms A timeout in milliseconds. A value of -1 means
|
||||
* infinite timeout.
|
||||
*
|
||||
* @return The number of bytes read, 0 on end of file, SSH_AGAIN on
|
||||
* timeout, SSH_ERROR on error.
|
||||
* @return The number of bytes read, 0 on end of file, `SSH_AGAIN`
|
||||
* on timeout, `SSH_ERROR` on error.
|
||||
*
|
||||
* @warning This function may return less than count bytes of data, and won't
|
||||
* block until count bytes have been read.
|
||||
@@ -3238,8 +3251,8 @@ int ssh_channel_read_timeout(ssh_channel channel,
|
||||
*
|
||||
* @param[in] is_stderr A boolean to select the stderr stream.
|
||||
*
|
||||
* @return The number of bytes read, SSH_AGAIN if nothing is
|
||||
* available, SSH_ERROR on error, and SSH_EOF if the channel is EOF.
|
||||
* @return The number of bytes read, `SSH_AGAIN` if nothing is
|
||||
* available, `SSH_ERROR` on error, and `SSH_EOF` if the channel is EOF.
|
||||
*
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
@@ -3296,11 +3309,11 @@ int ssh_channel_read_nonblocking(ssh_channel channel,
|
||||
* @param[in] is_stderr A boolean to select the stderr stream.
|
||||
*
|
||||
* @return The number of bytes available for reading, 0 if nothing
|
||||
* is available or SSH_ERROR on error.
|
||||
* is available or `SSH_ERROR` on error.
|
||||
* When a channel is freed the function returns
|
||||
* SSH_ERROR immediately.
|
||||
* `SSH_ERROR` immediately.
|
||||
*
|
||||
* @warning When the channel is in EOF state, the function returns SSH_EOF.
|
||||
* @warning When the channel is in EOF state, the function returns `SSH_EOF`.
|
||||
*
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
@@ -3343,18 +3356,19 @@ int ssh_channel_poll(ssh_channel channel, int is_stderr)
|
||||
*
|
||||
* @param[in] channel The channel to poll.
|
||||
* @param[in] timeout Set an upper limit on the time for which this function
|
||||
* will block, in milliseconds. Specifying a negative value
|
||||
* means an infinite timeout. This parameter is passed to
|
||||
* the poll() function.
|
||||
* will block, in milliseconds. Specifying a negative
|
||||
* value means an infinite timeout. This parameter is
|
||||
* passed to the poll() function.
|
||||
* @param[in] is_stderr A boolean to select the stderr stream.
|
||||
*
|
||||
* @return The number of bytes available for reading,
|
||||
* 0 if nothing is available (timeout elapsed),
|
||||
* SSH_EOF on end of file,
|
||||
* SSH_ERROR on error.
|
||||
* `SSH_EOF` on end of file,
|
||||
* `SSH_ERROR` on error.
|
||||
*
|
||||
* @warning When the channel is in EOF state, the function returns SSH_EOF.
|
||||
* When a channel is freed the function returns SSH_ERROR immediately.
|
||||
* @warning When the channel is in EOF state, the function returns `SSH_EOF`.
|
||||
* When a channel is freed the function returns `SSH_ERROR`
|
||||
* immediately.
|
||||
*
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
@@ -3455,12 +3469,12 @@ static int ssh_channel_exit_status_termination(void *c)
|
||||
* @param[out] pcore_dumped A pointer to store a boolean value if it dumped a
|
||||
* core.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_AGAIN if we don't have a status
|
||||
* or an SSH error.
|
||||
* @return `SSH_OK` on success, `SSH_AGAIN` if we don't have a
|
||||
* status or an SSH error.
|
||||
* @warning This function may block until a timeout (or never)
|
||||
* if the other side is not willing to close the channel.
|
||||
* When a channel is freed the function returns
|
||||
* SSH_ERROR immediately.
|
||||
* `SSH_ERROR` immediately.
|
||||
*
|
||||
* If you're looking for an async handling of this register a callback for the
|
||||
* exit status!
|
||||
@@ -3524,11 +3538,11 @@ int ssh_channel_get_exit_state(ssh_channel channel,
|
||||
* @param[in] channel The channel to get the status from.
|
||||
*
|
||||
* @return The exit status, -1 if no exit status has been returned
|
||||
* (yet), or SSH_ERROR on error.
|
||||
* (yet), or `SSH_ERROR` on error.
|
||||
* @warning This function may block until a timeout (or never)
|
||||
* if the other side is not willing to close the channel.
|
||||
* When a channel is freed the function returns
|
||||
* SSH_ERROR immediately.
|
||||
* `SSH_ERROR` immediately.
|
||||
*
|
||||
* If you're looking for an async handling of this register a callback for the
|
||||
* exit status.
|
||||
@@ -3641,9 +3655,9 @@ static size_t count_ptrs(ssh_channel *ptrs)
|
||||
*
|
||||
* @param[in] timeout Timeout as defined by select(2).
|
||||
*
|
||||
* @return SSH_OK on a successful operation, SSH_EINTR if the
|
||||
* @return `SSH_OK` on a successful operation, `SSH_EINTR` if the
|
||||
* select(2) syscall was interrupted, then relaunch the
|
||||
* function, or SSH_ERROR on error.
|
||||
* function, or `SSH_ERROR` on error.
|
||||
*/
|
||||
int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
||||
ssh_channel *exceptchans, struct timeval * timeout)
|
||||
@@ -3840,14 +3854,14 @@ int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len
|
||||
* @param[in] localport The source port (your local computer). It's optional
|
||||
* and for logging purpose.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*
|
||||
* @warning This function does not bind the local port and does not automatically
|
||||
* forward the content of a socket to the channel. You still have to
|
||||
* use ssh_channel_read and ssh_channel_write for this.
|
||||
* @warning This function does not bind the local port and does not
|
||||
* automatically forward the content of a socket to the channel. You
|
||||
* still have to use ssh_channel_read and ssh_channel_write for this.
|
||||
*/
|
||||
int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport)
|
||||
@@ -3905,13 +3919,13 @@ error:
|
||||
*
|
||||
* @param[in] orig_port The source port (the local server).
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR if an error occurred,
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* @return `SSH_OK` on success,
|
||||
* `SSH_ERROR` if an error occurred,
|
||||
* `SSH_AGAIN` if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
* @warning This function does not bind the local port and does not automatically
|
||||
* forward the content of a socket to the channel. You still have to
|
||||
* use shh_channel_read and ssh_channel_write for this.
|
||||
* @warning This function does not bind the local port and does not
|
||||
* automatically forward the content of a socket to the channel. You
|
||||
* still have to use shh_channel_read and ssh_channel_write for this.
|
||||
*/
|
||||
int ssh_channel_open_x11(ssh_channel channel,
|
||||
const char *orig_addr, int orig_port)
|
||||
@@ -3966,7 +3980,7 @@ error:
|
||||
*
|
||||
* @param[in] exit_status The exit status to send
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred.
|
||||
*/
|
||||
int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status)
|
||||
{
|
||||
@@ -4010,7 +4024,7 @@ error:
|
||||
* @param[in] errmsg A CRLF explanation text about the error condition
|
||||
* @param[in] lang The language used in the message (format: RFC 3066)
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR if an error occurred
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if an error occurred
|
||||
*/
|
||||
int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
|
||||
int core, const char *errmsg, const char *lang)
|
||||
|
||||
@@ -83,6 +83,20 @@ static ssize_t ssh_connector_fd_write(ssh_connector connector,
|
||||
uint32_t len);
|
||||
static bool ssh_connector_fd_is_socket(socket_t socket);
|
||||
|
||||
/**
|
||||
* @brief Create a new SSH connector.
|
||||
*
|
||||
* Allocates and initializes a new connector object for moving data between
|
||||
* an SSH session and file descriptors. The connector is created with invalid
|
||||
* file descriptors and callback structures initialized, but not yet attached
|
||||
* to any channels or sockets.
|
||||
*
|
||||
* @param[in] session The SSH session to associate with the connector.
|
||||
*
|
||||
* @return A newly allocated connector on success, or NULL if an
|
||||
* error occurred. On error, an out-of-memory error is
|
||||
* set on the session.
|
||||
*/
|
||||
ssh_connector ssh_connector_new(ssh_session session)
|
||||
{
|
||||
ssh_connector connector;
|
||||
@@ -112,6 +126,15 @@ ssh_connector ssh_connector_new(ssh_session session)
|
||||
return connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free an SSH connector.
|
||||
*
|
||||
* Cleans up and deallocates a connector created by ssh_connector_new().
|
||||
* Any channel callbacks and poll objects associated with the @p connector
|
||||
* are removed and freed before the connector structure itself is released.
|
||||
*
|
||||
* @param[in] connector The connector to free. Must not be NULL.
|
||||
*/
|
||||
void ssh_connector_free (ssh_connector connector)
|
||||
{
|
||||
if (connector->in_channel != NULL) {
|
||||
@@ -140,6 +163,24 @@ void ssh_connector_free (ssh_connector connector)
|
||||
free(connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the input channel for a connector.
|
||||
*
|
||||
* Associates an SSH channel with the @p connector as its input source and
|
||||
* installs the internal channel callbacks used for reading data. Any
|
||||
* configured input file descriptor is disabled and the connector will
|
||||
* receive data from the given channel only.
|
||||
*
|
||||
* If neither `SSH_CONNECTOR_STDOUT` nor `SSH_CONNECTOR_STDERR` is specified
|
||||
* in @p flags, `SSH_CONNECTOR_STDOUT` is used as the default.
|
||||
*
|
||||
* @param[in] connector The connector to configure.
|
||||
* @param[in] channel The SSH channel to use as input.
|
||||
* @param[in] flags A combination of ssh_connector_flags_e values
|
||||
* selecting which channel streams to read from.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on failure.
|
||||
*/
|
||||
int ssh_connector_set_in_channel(ssh_connector connector,
|
||||
ssh_channel channel,
|
||||
enum ssh_connector_flags_e flags)
|
||||
@@ -156,6 +197,24 @@ int ssh_connector_set_in_channel(ssh_connector connector,
|
||||
return ssh_add_channel_callbacks(channel, &connector->in_channel_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the output channel for a connector.
|
||||
*
|
||||
* Associates an SSH channel with the @p connector as its output target and
|
||||
* installs the internal channel callbacks used for writing data. Any
|
||||
* configured output file descriptor is disabled and the connector will
|
||||
* send data to the given channel only.
|
||||
*
|
||||
* If neither `SSH_CONNECTOR_STDOUT` nor `SSH_CONNECTOR_STDERR` is specified
|
||||
* in @p flags, `SSH_CONNECTOR_STDOUT` is used as the default.
|
||||
*
|
||||
* @param[in] connector The connector to configure.
|
||||
* @param[in] channel The SSH channel to use as output.
|
||||
* @param[in] flags A combination of ssh_connector_flags_e values
|
||||
* selecting which channel streams to write to.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on failure.
|
||||
*/
|
||||
int ssh_connector_set_out_channel(ssh_connector connector,
|
||||
ssh_channel channel,
|
||||
enum ssh_connector_flags_e flags)
|
||||
@@ -172,6 +231,15 @@ int ssh_connector_set_out_channel(ssh_connector connector,
|
||||
return ssh_add_channel_callbacks(channel, &connector->out_channel_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the connector's input file descriptor.
|
||||
*
|
||||
* Sets the @p fd (file descriptor) to be used as the input source for the
|
||||
* @p connector , replacing any previously configured input channel.
|
||||
*
|
||||
* @param[in] connector The connector to configure.
|
||||
* @param[in] fd The file descriptor (socket or regular).
|
||||
*/
|
||||
void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd)
|
||||
{
|
||||
connector->in_fd = fd;
|
||||
@@ -179,6 +247,15 @@ void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd)
|
||||
connector->in_channel = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the connector's output file descriptor.
|
||||
*
|
||||
* Sets the @p fd (file descriptor) to be used as the output target for the
|
||||
* @p connector , replacing any previously configured output channel.
|
||||
*
|
||||
* @param[in] connector The connector to configure.
|
||||
* @param[in] fd The file descriptor (socket or regular).
|
||||
*/
|
||||
void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd)
|
||||
{
|
||||
connector->out_fd = fd;
|
||||
@@ -372,7 +449,7 @@ ssh_connector_fd_out_cb(ssh_connector connector)
|
||||
*
|
||||
* @brief Callback called when a poll event is received on a file descriptor.
|
||||
*
|
||||
* This is for (input or output.
|
||||
* This is for input or output.
|
||||
*
|
||||
* @param[in] fd file descriptor receiving the event
|
||||
*
|
||||
|
||||
353
src/server.c
353
src/server.c
@@ -72,13 +72,21 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @internal
|
||||
/**
|
||||
* @internal
|
||||
* @brief Sets the server's key exchange, encryption, MAC, and compression
|
||||
* algorithms.
|
||||
*
|
||||
* @brief initialize the set of key exchange, hostkey, ciphers, MACs, and
|
||||
* compression algorithms for the given ssh_session
|
||||
* Prepares the server key exchange (KEX) proposals by prioritizing the
|
||||
* available host keys (Ed25519, ECDSA, RSA) based on their strength and fills
|
||||
* in the KEX method lists based on session options or defaults. This is
|
||||
* essential for negotiating secure communication parameters in the SSH
|
||||
* handshake.
|
||||
*
|
||||
* The selection of algorithms and keys used are determined by the
|
||||
* options that are currently set in the given ssh_session structure.
|
||||
* @param[in] session The SSH session to set up.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on failure (e.g., no host keys
|
||||
* available, random number generation error, or memory allocation failure).
|
||||
*/
|
||||
int server_set_kex(ssh_session session)
|
||||
{
|
||||
@@ -210,6 +218,23 @@ int ssh_server_init_kex(ssh_session session) {
|
||||
return server_set_kex(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Sends SSH extension information from the server to client.
|
||||
*
|
||||
* A server may send this message (`SSH_MSG_EXT_INFO`) after its first
|
||||
* `SSH_MSG_NEWKEYS` message or just before sending `SSH_MSG_USERAUTH_SUCCESS`
|
||||
* to provide additional extensions support that are not meant for an
|
||||
* unauthenticated client.
|
||||
*
|
||||
* If any error occurs during the packing or sending of the packet, the function
|
||||
* aborts to avoid partial or corrupted sends.
|
||||
*
|
||||
* @param[in] session The SSH session.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on failure.
|
||||
*/
|
||||
static int ssh_server_send_extensions(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
@@ -275,6 +300,22 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares server host key parameters for the key exchange process.
|
||||
*
|
||||
* Selects the appropriate private host key (RSA, ECDSA, or Ed25519) based on
|
||||
* the session's configured host key type, sets the corresponding @p digest
|
||||
* algorithm, and imports the public key blob into the Diffie-Hellman key
|
||||
* exchange state.
|
||||
*
|
||||
* @param[in] session The SSH session to which we are preparing host key
|
||||
* parameters.
|
||||
* @param[out] privkey Pointer to receive the selected private host key.
|
||||
* @param[out] digest Pointer to receive the host key digest algorithm.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` on failure (invalid key type, export
|
||||
* failure, or DH import error).
|
||||
*/
|
||||
int
|
||||
ssh_get_key_params(ssh_session session,
|
||||
ssh_key *privkey,
|
||||
@@ -668,6 +709,20 @@ int ssh_auth_reply_default(ssh_session session,int partial) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Sends default refusal for a channel open request.
|
||||
*
|
||||
* Default handler that rejects incoming SSH channel open requests by sending
|
||||
* a `SSH2_MSG_CHANNEL_OPEN_FAILURE` packet with "administratively prohibited"
|
||||
* reason code. Used when no custom channel open handler is registered.
|
||||
*
|
||||
* @param[in] msg The SSH message containing the channel open request details.
|
||||
*
|
||||
* @return `SSH_OK` on successful packet send; `SSH_ERROR` on buffer allocation
|
||||
* or packet send failure.
|
||||
*/
|
||||
static int ssh_message_channel_request_open_reply_default(ssh_message msg) {
|
||||
int rc;
|
||||
|
||||
@@ -689,6 +744,21 @@ static int ssh_message_channel_request_open_reply_default(ssh_message msg) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Sends default refusal for a channel request.
|
||||
*
|
||||
* Default handler that rejects incoming SSH channel requests. If the client
|
||||
* requested a reply (`want_reply`), sends `SSH2_MSG_CHANNEL_FAILURE` to the
|
||||
* specific channel. If no reply requested, logs the refusal and returns
|
||||
* success.
|
||||
*
|
||||
* @param[in] msg The SSH message containing the channel request details.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` if buffer allocation or packet send
|
||||
* fails.
|
||||
*/
|
||||
static int ssh_message_channel_request_reply_default(ssh_message msg) {
|
||||
uint32_t channel;
|
||||
int rc;
|
||||
@@ -722,11 +792,11 @@ static int ssh_message_service_request_reply_default(ssh_message msg) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends SERVICE_ACCEPT to the client
|
||||
* @brief Sends `SSH2_MSG_SERVICE_ACCEPT` to the client
|
||||
*
|
||||
* @param msg The message to reply to
|
||||
*
|
||||
* @returns SSH_OK when success otherwise SSH_ERROR
|
||||
* @returns `SSH_OK` when success otherwise `SSH_ERROR`
|
||||
*/
|
||||
int ssh_message_service_reply_success(ssh_message msg)
|
||||
{
|
||||
@@ -760,7 +830,7 @@ int ssh_message_service_reply_success(ssh_message msg)
|
||||
*
|
||||
* @param bound_port The remote bind port
|
||||
*
|
||||
* @returns SSH_OK on success, otherwise SSH_ERROR
|
||||
* @returns `SSH_OK` on success, otherwise `SSH_ERROR`
|
||||
*/
|
||||
int ssh_message_global_request_reply_success(ssh_message msg, uint16_t bound_port) {
|
||||
int rc;
|
||||
@@ -796,6 +866,20 @@ error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Sends default refusal for a global request.
|
||||
*
|
||||
* Default handler that rejects incoming SSH global requests. If the client
|
||||
* requested a reply (`want_reply`), sends `SSH2_MSG_REQUEST_FAILURE`. If no
|
||||
* reply requested, logs the refusal and returns success immediately.
|
||||
*
|
||||
* @param[in] msg The SSH message containing the global request details.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` if buffer allocation or packet send
|
||||
* fails.
|
||||
*/
|
||||
static int ssh_message_global_request_reply_default(ssh_message msg) {
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS, "Refusing a global request");
|
||||
|
||||
@@ -934,6 +1018,28 @@ int ssh_message_auth_set_methods(ssh_message msg, int methods) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an interactive authentication request message.
|
||||
*
|
||||
* Builds and sends an `SSH2_MSG_USERAUTH_INFO_REQUEST` packet containing the
|
||||
* given name and @p instruction, followed by a number of @p prompts with
|
||||
* associated @p echo flags to control whether user input is echoed.
|
||||
* It initializes the keyboard-interactive state in the session.
|
||||
*
|
||||
* @param[in] msg The SSH message representing the client
|
||||
* authentication request.
|
||||
* @param[in] name The name of the authentication request.
|
||||
* @param[in] instruction Instruction string with information for the user.
|
||||
* @param[in] num_prompts Number of prompts to send. The arrays prompts and
|
||||
* echo must both have num_prompts elements.
|
||||
* @param[in] prompts Array of @p num_prompts prompt strings to display.
|
||||
* @param[in] echo Array of num_prompts boolean values (0 or 1). A
|
||||
* non-zero value means the user input for that prompt
|
||||
* is echoed (visible); 0 means the input is hidden
|
||||
* (typically for passwords).
|
||||
*
|
||||
* @return `SSH_OK` on successful send; `SSH_ERROR` on failure.
|
||||
*/
|
||||
int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
|
||||
const char *instruction, unsigned int num_prompts,
|
||||
const char **prompts, char *echo) {
|
||||
@@ -1040,15 +1146,15 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends SSH2_MSG_USERAUTH_SUCCESS or SSH2_MSG_USERAUTH_FAILURE message
|
||||
* depending on the success of the authentication method
|
||||
* @brief Sends `SSH2_MSG_USERAUTH_SUCCESS` or `SSH2_MSG_USERAUTH_FAILURE`
|
||||
* message depending on the success of the authentication method
|
||||
*
|
||||
* @param session The session to reply to
|
||||
*
|
||||
* @param partial Denotes if the authentication process was partially completed
|
||||
* (unsuccessful)
|
||||
*
|
||||
* @returns SSH_OK on success, otherwise SSH_ERROR
|
||||
* @returns `SSH_OK` on success, otherwise `SSH_ERROR`
|
||||
*/
|
||||
int ssh_auth_reply_success(ssh_session session, int partial)
|
||||
{
|
||||
@@ -1072,9 +1178,9 @@ int ssh_auth_reply_success(ssh_session session, int partial)
|
||||
|
||||
/*
|
||||
* Consider the session as having been authenticated only after sending
|
||||
* the USERAUTH_SUCCESS message. Setting these flags after ssh_packet_send
|
||||
* ensures that a rekey is not triggered prematurely, causing the message
|
||||
* to be queued.
|
||||
* the `USERAUTH_SUCCESS` message. Setting these flags after
|
||||
* ssh_packet_send ensures that a rekey is not triggered prematurely,
|
||||
* causing the message to be queued.
|
||||
*/
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
|
||||
@@ -1093,6 +1199,18 @@ int ssh_auth_reply_success(ssh_session session, int partial)
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replies to an authentication request with success.
|
||||
*
|
||||
* Sends an authentication success message (`SSH2_MSG_USERAUTH_SUCCESS`) to the
|
||||
* client, or a partial success if further authentication steps are required.
|
||||
*
|
||||
* @param[in] msg The SSH authentication message being handled.
|
||||
* @param[in] partial Set to nonzero if partial success (more auth needed), zero
|
||||
* for full success.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` if msg is NULL or on send failure.
|
||||
*/
|
||||
int ssh_message_auth_reply_success(ssh_message msg, int partial) {
|
||||
if(msg == NULL)
|
||||
return SSH_ERROR;
|
||||
@@ -1100,7 +1218,7 @@ int ssh_message_auth_reply_success(ssh_message msg, int partial) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Answer SSH2_MSG_USERAUTH_PK_OK to a pubkey authentication request
|
||||
* @brief Answer `SSH2_MSG_USERAUTH_PK_OK` to a pubkey authentication request
|
||||
*
|
||||
* @param msg The message
|
||||
*
|
||||
@@ -1108,7 +1226,7 @@ int ssh_message_auth_reply_success(ssh_message msg, int partial) {
|
||||
*
|
||||
* @param pubkey The accepted public key
|
||||
*
|
||||
* @returns SSH_OK on success, otherwise SSH_ERROR
|
||||
* @returns `SSH_OK` on success, otherwise `SSH_ERROR`
|
||||
*/
|
||||
int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey) {
|
||||
int rc;
|
||||
@@ -1131,11 +1249,11 @@ int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pu
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Answer SSH2_MSG_USERAUTH_PK_OK to a pubkey authentication request
|
||||
* @brief Answer `SSH2_MSG_USERAUTH_PK_OK` to a pubkey authentication request
|
||||
*
|
||||
* @param msg The message
|
||||
*
|
||||
* @returns SSH_OK on success, otherwise SSH_ERROR
|
||||
* @returns `SSH_OK` on success, otherwise `SSH_ERROR`
|
||||
*/
|
||||
int ssh_message_auth_reply_pk_ok_simple(ssh_message msg)
|
||||
{
|
||||
@@ -1162,83 +1280,271 @@ int ssh_message_auth_reply_pk_ok_simple(ssh_message msg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the originator address from the channel open message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The originator address, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_open_originator(ssh_message msg){
|
||||
return msg->channel_request_open.originator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the originator port from the channel open message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The originator port.
|
||||
*/
|
||||
int ssh_message_channel_request_open_originator_port(ssh_message msg){
|
||||
return msg->channel_request_open.originator_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the destination address from the channel open message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The destination address, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_open_destination(ssh_message msg){
|
||||
return msg->channel_request_open.destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the destination port from the channel open message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The destination port.
|
||||
*/
|
||||
int ssh_message_channel_request_open_destination_port(ssh_message msg){
|
||||
return msg->channel_request_open.destination_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the channel associated with the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The channel associated with the message.
|
||||
*/
|
||||
ssh_channel ssh_message_channel_request_channel(ssh_message msg){
|
||||
return msg->channel_request.channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the terminal type from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The terminal type (e.g. "xterm"), or NULL.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function channel_pty_request_function.
|
||||
*
|
||||
* @see channel_pty_request_function.
|
||||
*/
|
||||
const char *ssh_message_channel_request_pty_term(ssh_message msg){
|
||||
return msg->channel_request.TERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the terminal width from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The terminal width in characters.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function channel_pty_request_function.
|
||||
*
|
||||
* @see channel_pty_request_function.
|
||||
*/
|
||||
int ssh_message_channel_request_pty_width(ssh_message msg){
|
||||
return msg->channel_request.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the terminal height from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The terminal height in characters.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function channel_pty_request_function.
|
||||
*
|
||||
* @see channel_pty_request_function.
|
||||
*/
|
||||
int ssh_message_channel_request_pty_height(ssh_message msg){
|
||||
return msg->channel_request.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the terminal pixel width from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The pixel width.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function channel_pty_request_function.
|
||||
*
|
||||
* @see channel_pty_request_function.
|
||||
*/
|
||||
int ssh_message_channel_request_pty_pxwidth(ssh_message msg){
|
||||
return msg->channel_request.pxwidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the terminal pixel height from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The pixel height.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function channel_pty_request_function.
|
||||
*
|
||||
* @see channel_pty_request_function.
|
||||
*/
|
||||
int ssh_message_channel_request_pty_pxheight(ssh_message msg){
|
||||
return msg->channel_request.pxheight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the name of the environment variable from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The variable name, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_env_name(ssh_message msg){
|
||||
return msg->channel_request.var_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the environment variable from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The variable value, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_env_value(ssh_message msg){
|
||||
return msg->channel_request.var_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the command from a channel request message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The command, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_command(ssh_message msg){
|
||||
return msg->channel_request.command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the subsystem from a channel request message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The subsystem, or NULL.
|
||||
*/
|
||||
const char *ssh_message_channel_request_subsystem(ssh_message msg){
|
||||
return msg->channel_request.subsystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the X11 request is for a single connection.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return 1 if single connection, 0 otherwise.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function
|
||||
* channel_open_request_x11_function.
|
||||
*
|
||||
* @see channel_open_request_x11_function.
|
||||
*/
|
||||
int ssh_message_channel_request_x11_single_connection(ssh_message msg){
|
||||
return msg->channel_request.x11_single_connection ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the X11 authentication protocol from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The authentication protocol, or NULL.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function
|
||||
* channel_open_request_x11_function.
|
||||
*
|
||||
* @see channel_open_request_x11_function.
|
||||
*/
|
||||
const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg){
|
||||
return msg->channel_request.x11_auth_protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the X11 authentication cookie from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The authentication cookie, or NULL.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function
|
||||
* channel_open_request_x11_function.
|
||||
*
|
||||
* @see channel_open_request_x11_function.
|
||||
*/
|
||||
const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg){
|
||||
return msg->channel_request.x11_auth_cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the X11 screen number from the message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The screen number.
|
||||
*
|
||||
* @deprecated This function should not be used anymore as there is a
|
||||
* callback based server implementation function
|
||||
* channel_open_request_x11_function.
|
||||
*
|
||||
* @see channel_open_request_x11_function.
|
||||
*/
|
||||
int ssh_message_channel_request_x11_screen_number(ssh_message msg){
|
||||
return msg->channel_request.x11_screen_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the bind address from the global request message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The bind address, or NULL.
|
||||
*/
|
||||
const char *ssh_message_global_request_address(ssh_message msg){
|
||||
return msg->global_request.bind_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the bind port from the global request message.
|
||||
*
|
||||
* @param[in] msg The message.
|
||||
*
|
||||
* @return The bind port.
|
||||
*/
|
||||
int ssh_message_global_request_port(ssh_message msg){
|
||||
return msg->global_request.bind_port;
|
||||
}
|
||||
@@ -1258,6 +1564,13 @@ void ssh_set_message_callback(ssh_session session,
|
||||
session->ssh_message_callback_data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute callbacks for the messages in the queue.
|
||||
*
|
||||
* @param[in] session The session.
|
||||
*
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*/
|
||||
int ssh_execute_message_callbacks(ssh_session session){
|
||||
ssh_message msg=NULL;
|
||||
int ret;
|
||||
@@ -1293,7 +1606,7 @@ int ssh_execute_message_callbacks(ssh_session session){
|
||||
*
|
||||
* @param session The session to send the message to
|
||||
*
|
||||
* @returns SSH_OK
|
||||
* @returns `SSH_OK`
|
||||
*/
|
||||
int ssh_send_keepalive(ssh_session session)
|
||||
{
|
||||
|
||||
@@ -646,10 +646,9 @@ static int ssh_flush_termination(void *c){
|
||||
* will block, in milliseconds. Specifying -1
|
||||
* means an infinite timeout. This parameter is passed to
|
||||
* the poll() function.
|
||||
* @returns SSH_OK on success, SSH_AGAIN if timeout occurred,
|
||||
* SSH_ERROR otherwise.
|
||||
* @returns `SSH_OK` on success, `SSH_AGAIN` if timeout occurred,
|
||||
* `SSH_ERROR` otherwise.
|
||||
*/
|
||||
|
||||
int ssh_blocking_flush(ssh_session session, int timeout){
|
||||
int rc;
|
||||
if (session == NULL) {
|
||||
@@ -731,7 +730,7 @@ void ssh_set_fd_towrite(ssh_session session) {
|
||||
/**
|
||||
* @brief Tell the session it has an exception to catch on the file descriptor.
|
||||
*
|
||||
* \param[in] session The ssh session to use.
|
||||
* @param[in] session The ssh session to use.
|
||||
*/
|
||||
void ssh_set_fd_except(ssh_session session) {
|
||||
if (session == NULL) {
|
||||
@@ -745,20 +744,22 @@ void ssh_set_fd_except(ssh_session session) {
|
||||
* @internal
|
||||
*
|
||||
* @brief Poll the current session for an event and call the appropriate
|
||||
* callbacks. This function will not loop until the timeout is expired.
|
||||
* callbacks. This function will not loop until the @p timeout is expired.
|
||||
*
|
||||
* This will block until one event happens.
|
||||
*
|
||||
* @param[in] session The session handle to use.
|
||||
*
|
||||
* @param[in] timeout Set an upper limit on the time for which this function
|
||||
* will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
|
||||
* will block, in milliseconds. Specifying
|
||||
* `SSH_TIMEOUT_INFINITE`
|
||||
* (-1) means an infinite timeout.
|
||||
* Specifying SSH_TIMEOUT_USER means to use the timeout
|
||||
* specified in options. 0 means poll will return immediately.
|
||||
* Specifying `SSH_TIMEOUT_USER` means to use the timeout
|
||||
* specified in options. 0 means poll will return
|
||||
* immediately.
|
||||
* This parameter is passed to the poll() function.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` otherwise.
|
||||
*/
|
||||
int ssh_handle_packets(ssh_session session, int timeout)
|
||||
{
|
||||
@@ -813,13 +814,14 @@ int ssh_handle_packets(ssh_session session, int timeout)
|
||||
* @brief Poll the current session for an event and call the appropriate
|
||||
* callbacks.
|
||||
*
|
||||
* This will block until termination function returns true, or timeout expired.
|
||||
* This will block until termination function returns true, or @p timeout
|
||||
* expired.
|
||||
*
|
||||
* @param[in] session The session handle to use.
|
||||
*
|
||||
* @param[in] timeout Set an upper limit on the time for which this function
|
||||
* will block, in milliseconds. Specifying
|
||||
* SSH_TIMEOUT_INFINITE (-1) means an infinite timeout.
|
||||
* `SSH_TIMEOUT_INFINITE` (-1) means an infinite timeout.
|
||||
* Specifying SSH_TIMEOUT_USER means using the timeout
|
||||
* specified in options. 0 means poll will return
|
||||
* immediately.
|
||||
@@ -830,8 +832,8 @@ int ssh_handle_packets(ssh_session session, int timeout)
|
||||
* @param[in] fct Termination function to be used to determine if it is
|
||||
* possible to stop polling.
|
||||
* @param[in] user User parameter to be passed to fct termination function.
|
||||
* @returns SSH_OK on success, SSH_AGAIN if timeout occurred,
|
||||
* SSH_ERROR otherwise.
|
||||
* @returns `SSH_OK` on success, `SSH_AGAIN` if timeout occurred,
|
||||
* `SSH_ERROR` otherwise.
|
||||
*/
|
||||
int ssh_handle_packets_termination(ssh_session session,
|
||||
int timeout,
|
||||
@@ -888,9 +890,10 @@ int ssh_handle_packets_termination(ssh_session session,
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @returns A bitmask including SSH_CLOSED, SSH_READ_PENDING, SSH_WRITE_PENDING
|
||||
* or SSH_CLOSED_ERROR which respectively means the session is closed,
|
||||
* has data to read on the connection socket and session was closed
|
||||
* @returns A bitmask including `SSH_CLOSED`, `SSH_READ_PENDING`,
|
||||
* `SSH_WRITE_PENDING` or `SSH_CLOSED_ERROR` which
|
||||
* respectively means the session is closed, has data to
|
||||
* read on the connection socket and session was closed
|
||||
* due to an error.
|
||||
*/
|
||||
int ssh_get_status(ssh_session session) {
|
||||
@@ -926,9 +929,9 @@ int ssh_get_status(ssh_session session) {
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @returns A bitmask including SSH_READ_PENDING or SSH_WRITE_PENDING.
|
||||
* For SSH_READ_PENDING, your invocation of poll() should include
|
||||
* POLLIN. For SSH_WRITE_PENDING, your invocation of poll() should
|
||||
* @returns A bitmask including `SSH_READ_PENDING` or `SSH_WRITE_PENDING`.
|
||||
* For `SSH_READ_PENDING`, your invocation of poll() should include
|
||||
* POLLIN. For `SSH_WRITE_PENDING`, your invocation of poll() should
|
||||
* include POLLOUT.
|
||||
*/
|
||||
int ssh_get_poll_flags(ssh_session session)
|
||||
@@ -1036,7 +1039,7 @@ void ssh_socket_exception_callback(int code, int errno_code, void *user){
|
||||
* @param[in] session The SSH session
|
||||
* @param[in] data Data to be sent
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` otherwise.
|
||||
*/
|
||||
int ssh_send_ignore (ssh_session session, const char *data) {
|
||||
const int type = SSH2_MSG_IGNORE;
|
||||
@@ -1071,7 +1074,7 @@ error:
|
||||
* SHOULD NOT be displayed unless debugging
|
||||
* information has been explicitly requested.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` otherwise.
|
||||
*/
|
||||
int ssh_send_debug (ssh_session session, const char *message, int always_display) {
|
||||
int rc;
|
||||
@@ -1237,7 +1240,7 @@ void ssh_clean_pubkey_hash(unsigned char **hash)
|
||||
* @param[out] key A pointer to store the allocated key. You need to free
|
||||
* the key using ssh_key_free().
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
* @return `SSH_OK` on success, `SSH_ERROR` on error.
|
||||
*
|
||||
* @see ssh_key_free()
|
||||
*/
|
||||
@@ -1271,7 +1274,7 @@ int ssh_get_publickey(ssh_session session, ssh_key *key)
|
||||
/**
|
||||
* @brief Allocates a buffer with the hash of the public key.
|
||||
*
|
||||
* This function allows you to get a hash of the public key. You can then
|
||||
* This function allows you to get a @p hash of the public @p key. You can then
|
||||
* print this hash in a human-readable form to the user so that he is able to
|
||||
* verify it. Use ssh_get_hexa() or ssh_print_hash() to display it.
|
||||
*
|
||||
|
||||
242
src/sftpserver.c
242
src/sftpserver.c
@@ -60,6 +60,27 @@
|
||||
#define MAX_ENTRIES_NUM_IN_PACKET 50
|
||||
#define MAX_LONG_NAME_LEN 350
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Creates an SFTP client message from a received packet.
|
||||
*
|
||||
* Allocates and initializes a sftp_client_message structure from a raw
|
||||
* SFTP packet. Copies the complete @p packet payload and parses common
|
||||
* fields such as message type, request id, and message-specific data
|
||||
* (handle, filename, attributes, offsets, etc.) depending on the SFTP
|
||||
* message type.
|
||||
*
|
||||
* On success, the returned message owns its internal buffers and must
|
||||
* be freed with sftp_client_message_free().
|
||||
*
|
||||
* @param[in] sftp The SFTP session associated with the packet.
|
||||
* @param[in] packet The received SFTP packet to decode.
|
||||
*
|
||||
* @return A newly allocated sftp_client_message on success, or NULL on
|
||||
* error (memory allocation failure, malformed packet, or
|
||||
* unsupported message type).
|
||||
*/
|
||||
static sftp_client_message
|
||||
sftp_make_client_message(sftp_session sftp, sftp_packet packet)
|
||||
{
|
||||
@@ -256,6 +277,17 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the next SFTP client message from the session.
|
||||
*
|
||||
* Reads a single SFTP packet from the given SFTP session and converts it
|
||||
* into a parsed sftp_client_message structure.
|
||||
*
|
||||
* @param[in] sftp The SFTP session to read from.
|
||||
*
|
||||
* @return A newly allocated sftp_client_message on success; NULL if no packet
|
||||
* is available or an error occurs.
|
||||
*/
|
||||
sftp_client_message sftp_get_client_message(sftp_session sftp)
|
||||
{
|
||||
sftp_packet packet = NULL;
|
||||
@@ -286,22 +318,62 @@ sftp_get_client_message_from_packet(sftp_session sftp)
|
||||
return sftp_make_client_message(sftp, packet);
|
||||
}
|
||||
|
||||
/* Send an sftp client message. Can be used in case of proxying */
|
||||
/**
|
||||
* @brief Send an SFTP client message.
|
||||
*
|
||||
* Writes the given client message as a packet using the stored message
|
||||
* type and complete_message buffer. Can be used in case of proxying.
|
||||
*
|
||||
* @param[in] sftp The SFTP session.
|
||||
* @param[in] msg The client message to send.
|
||||
*
|
||||
* @return 0 on success; -1 on error from sftp_packet_write().
|
||||
*/
|
||||
int sftp_send_client_message(sftp_session sftp, sftp_client_message msg)
|
||||
{
|
||||
return sftp_packet_write(sftp, msg->type, msg->complete_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the SFTP client message type.
|
||||
*
|
||||
* Returns the SFTP packet type associated with the given client message
|
||||
* (for example `SSH_FXP_READ`, `SSH_FXP_WRITE`, `SSH_FXP_OPEN`, ...).
|
||||
*
|
||||
* @param[in] msg The SFTP client message.
|
||||
*
|
||||
* @return The SFTP message type as an unsigned 8-bit value.
|
||||
*/
|
||||
uint8_t sftp_client_message_get_type(sftp_client_message msg)
|
||||
{
|
||||
return msg->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the filename associated with an SFTP client message.
|
||||
*
|
||||
* Returns the filename carried by the given SFTP client message, if the
|
||||
* message type includes a filename field (for example OPEN, REMOVE, RENAME).
|
||||
*
|
||||
* @param[in] msg The SFTP client message.
|
||||
*
|
||||
* @return Filename string, or NULL if no filename
|
||||
* is associated with the message.
|
||||
*/
|
||||
const char *sftp_client_message_get_filename(sftp_client_message msg)
|
||||
{
|
||||
return msg->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the filename associated with an SFTP client message.
|
||||
*
|
||||
* Replaces the current filename stored in the client message with a copy
|
||||
* of the given @p newname string.
|
||||
*
|
||||
* @param[in] msg The SFTP client message to modify.
|
||||
* @param[in] newname The new filename to store in the message.
|
||||
*/
|
||||
void
|
||||
sftp_client_message_set_filename(sftp_client_message msg, const char *newname)
|
||||
{
|
||||
@@ -309,6 +381,17 @@ sftp_client_message_set_filename(sftp_client_message msg, const char *newname)
|
||||
msg->filename = strdup(newname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the data field of an SFTP client message as a string.
|
||||
*
|
||||
* Converts the internal ssh_string data field to a string
|
||||
* on first use and caches the result in the message. Subsequent calls
|
||||
* return the cached pointer.
|
||||
*
|
||||
* @param[in] msg The SFTP client message.
|
||||
*
|
||||
* @return The data as string, or NULL on error.
|
||||
*/
|
||||
const char *sftp_client_message_get_data(sftp_client_message msg)
|
||||
{
|
||||
if (msg->str_data == NULL)
|
||||
@@ -316,16 +399,48 @@ const char *sftp_client_message_get_data(sftp_client_message msg)
|
||||
return msg->str_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the flags associated with an SFTP client message.
|
||||
*
|
||||
* Returns the flags field stored in the given SFTP client message. The exact
|
||||
* meaning of the flags depends on the SFTP message type (for example, open
|
||||
* or stat flags).
|
||||
*
|
||||
* @param[in] msg The SFTP client message.
|
||||
*
|
||||
* @return The flags value as an unsigned 32-bit integer.
|
||||
*/
|
||||
uint32_t sftp_client_message_get_flags(sftp_client_message msg)
|
||||
{
|
||||
return msg->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the submessage name associated with an SFTP client message.
|
||||
*
|
||||
* Returns the submessage string stored in the given SFTP client message.
|
||||
* This is typically used for vendor-specific SFTP operations.
|
||||
*
|
||||
* @param[in] msg The SFTP client message.
|
||||
*
|
||||
* @return The submessage name as a string, or NULL if no
|
||||
* submessage is associated with the message.
|
||||
*/
|
||||
const char *sftp_client_message_get_submessage(sftp_client_message msg)
|
||||
{
|
||||
return msg->submessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free an SFTP client message and its associated resources.
|
||||
*
|
||||
* Releases all dynamically allocated fields in the SFTP client message
|
||||
* (such as filename, submessage, data, handle, attributes, and cached
|
||||
* buffers) and then frees the message structure itself. The function
|
||||
* does nothing if msg is NULL.
|
||||
*
|
||||
* @param[in] msg The SFTP client message to free, or NULL.
|
||||
*/
|
||||
void sftp_client_message_free(sftp_client_message msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
@@ -343,6 +458,20 @@ void sftp_client_message_free(sftp_client_message msg)
|
||||
SAFE_FREE(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an SFTP NAME reply for a client message.
|
||||
*
|
||||
* Builds and sends an `SSH_FXP_NAME` packet in response to the given
|
||||
* SFTP client message, containing a single filename and its attributes.
|
||||
* The function encodes the message id, the count of returned names
|
||||
* (always 1), the filename fields and the provided attributes.
|
||||
*
|
||||
* @param[in] msg The SFTP client message being answered.
|
||||
* @param[in] name The filename to return to the client.
|
||||
* @param[in] attr The file attributes associated with the filename.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation failure or packet send error.
|
||||
*/
|
||||
int
|
||||
sftp_reply_name(sftp_client_message msg, const char *name, sftp_attributes attr)
|
||||
{
|
||||
@@ -378,6 +507,19 @@ sftp_reply_name(sftp_client_message msg, const char *name, sftp_attributes attr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an SFTP HANDLE reply for a client message.
|
||||
*
|
||||
* Builds and sends an `SSH_FXP_HANDLE` packet in response to the given
|
||||
* SFTP client message, containing the provided file @p handle. The message
|
||||
* id is taken from the client message and the handle is encoded as an
|
||||
* SSH string.
|
||||
*
|
||||
* @param[in] msg The SFTP client message being answered.
|
||||
* @param[in] handle The file handle to return to the client.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation failure or packet send error.
|
||||
*/
|
||||
int sftp_reply_handle(sftp_client_message msg, ssh_string handle)
|
||||
{
|
||||
ssh_buffer out;
|
||||
@@ -402,6 +544,18 @@ int sftp_reply_handle(sftp_client_message msg, ssh_string handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an SFTP ATTRS reply for a client message.
|
||||
*
|
||||
* Builds and sends an `SSH_FXP_ATTRS` packet in response to the given
|
||||
* SFTP client message, encoding the message id and the provided file
|
||||
* attributes.
|
||||
*
|
||||
* @param[in] msg The SFTP client message being answered.
|
||||
* @param[in] attr The file attributes to return to the client.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation failure or packet send error.
|
||||
*/
|
||||
int sftp_reply_attr(sftp_client_message msg, sftp_attributes attr)
|
||||
{
|
||||
ssh_buffer out;
|
||||
@@ -424,6 +578,20 @@ int sftp_reply_attr(sftp_client_message msg, sftp_attributes attr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add one name entry to a multi-name SFTP reply.
|
||||
*
|
||||
* Appends a @p file name, @p longname and attributes to the buffered NAME reply
|
||||
* stored in the client message. Can be called multiple times before the
|
||||
* reply is sent.
|
||||
*
|
||||
* @param[in] msg The SFTP client message being prepared.
|
||||
* @param[in] file The filename to add.
|
||||
* @param[in] longname The long name to add.
|
||||
* @param[in] attr The file attributes for this entry.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation or buffer write error.
|
||||
*/
|
||||
int
|
||||
sftp_reply_names_add(sftp_client_message msg, const char *file,
|
||||
const char *longname, sftp_attributes attr)
|
||||
@@ -464,6 +632,17 @@ sftp_reply_names_add(sftp_client_message msg, const char *file,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a multi-name SFTP reply.
|
||||
*
|
||||
* Sends an `SSH_FXP_NAME` packet for the given client message using the
|
||||
* accumulated name entries stored in msg->attrbuf and msg->attr_num.
|
||||
* After sending, the buffer and counter are reset.
|
||||
*
|
||||
* @param[in] msg The SFTP client message to reply to.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation or packet send error.
|
||||
*/
|
||||
int sftp_reply_names(sftp_client_message msg)
|
||||
{
|
||||
ssh_buffer out;
|
||||
@@ -495,6 +674,20 @@ int sftp_reply_names(sftp_client_message msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an SFTP STATUS reply.
|
||||
*
|
||||
* Sends an `SSH_FXP_STATUS` packet for the given client message, including
|
||||
* the @p status code and an optional human readable @p message. The language
|
||||
* tag is sent as an empty string.
|
||||
*
|
||||
* @param[in] msg The SFTP client message to reply to.
|
||||
* @param[in] status The SFTP status code to send (e.g. `SSH_FX_OK`,
|
||||
* `SSH_FX_FAILURE`).
|
||||
* @param[in] message Optional text message describing the status, or NULL.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation or packet send error.
|
||||
*/
|
||||
int
|
||||
sftp_reply_status(sftp_client_message msg, uint32_t status, const char *message)
|
||||
{
|
||||
@@ -531,6 +724,18 @@ sftp_reply_status(sftp_client_message msg, uint32_t status, const char *message)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an SFTP DATA reply.
|
||||
*
|
||||
* Sends an `SSH_FXP_DATA` packet for the given client message, containing
|
||||
* the provided data buffer and its length.
|
||||
*
|
||||
* @param[in] msg The SFTP client message to reply to.
|
||||
* @param[in] data The data buffer to send.
|
||||
* @param[in] len Number of bytes from data to send.
|
||||
*
|
||||
* @return 0 on success; -1 on memory allocation or packet send error.
|
||||
*/
|
||||
int sftp_reply_data(sftp_client_message msg, const void *data, int len)
|
||||
{
|
||||
ssh_buffer out;
|
||||
@@ -646,12 +851,18 @@ int sftp_reply_version(sftp_client_message client_msg)
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function will return you a new handle to give the client.
|
||||
* the function accepts an info that can be retrieved later with
|
||||
* the handle. Care is given that a corrupted handle won't give a
|
||||
* valid info (or worse).
|
||||
/**
|
||||
* @brief Allocate a new SFTP handle slot.
|
||||
*
|
||||
* Finds a free handle slot in the SFTP session, stores the given @p info
|
||||
* there and returns a 4-byte ssh_string that encodes the handle
|
||||
* index.
|
||||
*
|
||||
* @param[in] sftp The SFTP session.
|
||||
* @param[in] info Info to be stored in the handle slot.
|
||||
*
|
||||
* @return A new handle as ssh_string on success; NULL if no slot is
|
||||
* available or on memory allocation failure.
|
||||
*/
|
||||
ssh_string sftp_handle_alloc(sftp_session sftp, void *info)
|
||||
{
|
||||
@@ -688,6 +899,19 @@ ssh_string sftp_handle_alloc(sftp_session sftp, void *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resolve an SFTP handle to its stored info.
|
||||
*
|
||||
* Decodes the 4-byte @p handle value, checks bounds and returns the pointer
|
||||
* stored in the corresponding handle slot in the SFTP session.
|
||||
*
|
||||
* @param[in] sftp The SFTP session.
|
||||
* @param[in] handle The handle value as ssh_string.
|
||||
*
|
||||
* @return The stored pointer on success, or NULL if the handle table is
|
||||
* not initialized, the handle size is invalid, or the index is
|
||||
* out of range.
|
||||
*/
|
||||
void *sftp_handle(sftp_session sftp, ssh_string handle)
|
||||
{
|
||||
uint32_t val;
|
||||
@@ -1787,8 +2011,8 @@ process_client_message(sftp_client_message client_msg)
|
||||
* @param[out] userdata The pointer to sftp_session which will get the
|
||||
* resulting SFTP session
|
||||
*
|
||||
* @return SSH_OK when the SFTP server was successfully initialized, SSH_ERROR
|
||||
* otherwise.
|
||||
* @return `SSH_OK` when the SFTP server was successfully initialized,
|
||||
* `SSH_ERROR` otherwise.
|
||||
*/
|
||||
int
|
||||
sftp_channel_default_subsystem_request(ssh_session session,
|
||||
|
||||
301
src/socket.c
301
src/socket.c
@@ -112,8 +112,14 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
uint32_t len);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief inits the socket system (windows specific)
|
||||
* @internal
|
||||
*
|
||||
* @brief Initialize socket support for libssh.
|
||||
*
|
||||
* Initializes the socket subsystem, calling WSAStartup() on Windows and
|
||||
* ssh_poll_init() on all platforms. Can be called multiple times.
|
||||
*
|
||||
* @return 0 on success; -1 on Windows socket initialization failure.
|
||||
*/
|
||||
int ssh_socket_init(void)
|
||||
{
|
||||
@@ -135,7 +141,12 @@ int ssh_socket_init(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cleanup the socket system.
|
||||
* @internal
|
||||
*
|
||||
* @brief Cleanup socket support for libssh.
|
||||
*
|
||||
* Cleans up the socket subsystem, calling ssh_poll_cleanup() on all platforms
|
||||
* and WSACleanup() on Windows. Can be called multiple times.
|
||||
*/
|
||||
void ssh_socket_cleanup(void)
|
||||
{
|
||||
@@ -148,10 +159,17 @@ void ssh_socket_cleanup(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief creates a new Socket object
|
||||
* @internal
|
||||
*
|
||||
* @brief Allocate and initialize a new SSH socket structure.
|
||||
*
|
||||
* Creates a new ssh_socket structure associated with the given session,
|
||||
* initializes input/output buffers and sets default socket state.
|
||||
*
|
||||
* @param[in] session The SSH session to associate with the socket.
|
||||
*
|
||||
* @return A new ssh_socket on success; NULL on memory allocation failure.
|
||||
*/
|
||||
ssh_socket ssh_socket_new(ssh_session session)
|
||||
{
|
||||
@@ -189,8 +207,13 @@ ssh_socket ssh_socket_new(ssh_session session)
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Reset the state of a socket so it looks brand-new
|
||||
* @param[in] s socket to rest
|
||||
*
|
||||
* @brief Reset the state of a socket, so it looks brand new.
|
||||
*
|
||||
* Clears the file descriptor, reinitializes input/output buffers, frees
|
||||
* the poll handle if present, and resets all socket state flags.
|
||||
*
|
||||
* @param[in] s The SSH socket to reset.
|
||||
*/
|
||||
void ssh_socket_reset(ssh_socket s)
|
||||
{
|
||||
@@ -219,24 +242,36 @@ void ssh_socket_reset(ssh_socket s)
|
||||
* @param s socket to set callbacks on.
|
||||
* @param callbacks a ssh_socket_callback object reference.
|
||||
*/
|
||||
|
||||
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks)
|
||||
{
|
||||
s->callbacks = callbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Mark an SSH socket as connected.
|
||||
*
|
||||
* Sets the socket state to connected and configures the poll handle
|
||||
* to wait for `POLLIN` and `POLLOUT` events (needed for non-blocking connect).
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[in] p The poll handle to configure, or NULL.
|
||||
*/
|
||||
void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p)
|
||||
{
|
||||
s->state = SSH_SOCKET_CONNECTED;
|
||||
/* POLLOUT is the event to wait for in a nonblocking connect */
|
||||
/* `POLLOUT` is the event to wait for in a non-blocking connect */
|
||||
if (p != NULL) {
|
||||
ssh_poll_set_events(p, POLLIN | POLLOUT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SSH poll callback. This callback will be used when an event
|
||||
* caught on the socket.
|
||||
* @internal
|
||||
*
|
||||
* @brief SSH poll callback. This callback will be used when an
|
||||
* event caught on the socket.
|
||||
*
|
||||
* @param p Poll object this callback belongs to.
|
||||
* @param fd The raw socket.
|
||||
@@ -416,8 +451,15 @@ ssh_poll_handle ssh_socket_get_poll_handle(ssh_socket s)
|
||||
return s->poll_handle;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Deletes a socket object
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Deletes a socket object.
|
||||
*
|
||||
* Closes the socket connection, frees input/output buffers and
|
||||
* releases the socket structure memory.
|
||||
*
|
||||
* @param[in] s The SSH socket to free, or NULL.
|
||||
*/
|
||||
void ssh_socket_free(ssh_socket s)
|
||||
{
|
||||
@@ -430,6 +472,20 @@ void ssh_socket_free(ssh_socket s)
|
||||
SAFE_FREE(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Connect an SSH socket to a Unix domain socket.
|
||||
*
|
||||
* Creates a Unix domain socket connection to the given @p path and associates
|
||||
* it with the SSH socket.
|
||||
*
|
||||
* @param[in] s The SSH socket to connect.
|
||||
* @param[in] path Path to the Unix domain socket.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` on socket creation, connect, or fd
|
||||
* setup failure.
|
||||
*/
|
||||
int ssh_socket_unix(ssh_socket s, const char *path)
|
||||
{
|
||||
struct sockaddr_un sunaddr;
|
||||
@@ -466,8 +522,17 @@ int ssh_socket_unix(ssh_socket s, const char *path)
|
||||
return ssh_socket_set_fd(s, fd);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief closes a socket
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Close an SSH socket.
|
||||
*
|
||||
* Closes the socket file descriptor if open, saves the last error code,
|
||||
* frees the poll handle if unlocked, and marks the socket state as closed.
|
||||
* On Unix, attempts to terminate and wait for any running proxy command
|
||||
* process.
|
||||
*
|
||||
* @param[in] s The SSH socket to close.
|
||||
*/
|
||||
void ssh_socket_close(ssh_socket s)
|
||||
{
|
||||
@@ -545,24 +610,48 @@ int ssh_socket_set_fd(ssh_socket s, socket_t fd)
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief returns the input file descriptor of the socket
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Returns the input file descriptor of a socket.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return The socket file descriptor (socket_t).
|
||||
*/
|
||||
socket_t ssh_socket_get_fd(ssh_socket s)
|
||||
{
|
||||
return s->fd;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief returns nonzero if the socket is open
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Check if an SSH socket is open.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return Non-zero if socket is open, 0 if closed or invalid.
|
||||
*/
|
||||
int ssh_socket_is_open(ssh_socket s)
|
||||
{
|
||||
return s->fd != SSH_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief read len bytes from socket into buffer
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Perform an unbuffered read from an SSH socket.
|
||||
*
|
||||
* Reads @p len bytes from the socket file descriptor directly into @p buffer,
|
||||
* using `recv()` if the descriptor is a socket, or `read()` otherwise.
|
||||
* Updates internal error and state flags based on the result.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[out] buffer Buffer to read data into.
|
||||
* @param[in] len Maximum number of bytes to read.
|
||||
*
|
||||
* @return Number of bytes read on success, or -1 on error.
|
||||
*/
|
||||
static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
|
||||
void *buffer,
|
||||
@@ -594,8 +683,21 @@ static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief writes len bytes from buffer to socket
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Perform an unbuffered write to an SSH socket.
|
||||
*
|
||||
* Writes @p len bytes from @p buffer to the socket file descriptor,
|
||||
* using `send()` if the descriptor is a socket or `write()` otherwise.
|
||||
* Updates internal error and state flags, and re-enables POLLOUT
|
||||
* polling if a poll handle exists.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[in] buffer Buffer containing data to write.
|
||||
* @param[in] len Number of bytes to write.
|
||||
*
|
||||
* @return Number of bytes written on success, or -1 on error.
|
||||
*/
|
||||
static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
const void *buffer,
|
||||
@@ -636,8 +738,18 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
return w;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief returns nonzero if the current socket is in the fd_set
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Check if SSH socket file descriptor is set in an fd_set.
|
||||
*
|
||||
* Tests if the socket's file descriptor is present in the
|
||||
* given @p set (fd_set) . Returns 0 if the socket has no valid file descriptor.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[in] set The fd_set to test against.
|
||||
*
|
||||
* @return Non-zero if the socket fd is set in the fd_set, 0 otherwise.
|
||||
*/
|
||||
int ssh_socket_fd_isset(ssh_socket s, fd_set *set)
|
||||
{
|
||||
@@ -647,10 +759,17 @@ int ssh_socket_fd_isset(ssh_socket s, fd_set *set)
|
||||
return FD_ISSET(s->fd,set);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief sets the current fd in a fd_set and updates the max_fd
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Add SSH socket file descriptor to an fd_set.
|
||||
*
|
||||
* Adds the socket's file descriptor to the given @p set (fd_set)
|
||||
* and updates @p max_fd if this socket has the highest file descriptor number.
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[in,out] set The fd_set to add the socket to.
|
||||
* @param[in,out] max_fd the maximum fd value.
|
||||
*/
|
||||
|
||||
void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd)
|
||||
{
|
||||
if (s->fd == SSH_INVALID_SOCKET) {
|
||||
@@ -666,10 +785,21 @@ void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd)
|
||||
}
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief buffered write of data
|
||||
* \returns SSH_OK, or SSH_ERROR
|
||||
* \warning has no effect on socket before a flush
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Write data to an SSH socket output buffer.
|
||||
*
|
||||
* Adds the data to the socket's output @p buffer and calls a nonblocking
|
||||
* flush attempt to send buffered data.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
* @param[in] buffer Data to write.
|
||||
* @param[in] len Number of bytes to write.
|
||||
*
|
||||
* @return `SSH_OK` on success; `SSH_ERROR` on buffer allocation failure.
|
||||
*
|
||||
* @warning It has no effect on socket before a flush.
|
||||
*/
|
||||
int ssh_socket_write(ssh_socket s, const void *buffer, uint32_t len)
|
||||
{
|
||||
@@ -684,10 +814,22 @@ int ssh_socket_write(ssh_socket s, const void *buffer, uint32_t len)
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief starts a nonblocking flush of the output buffer
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Starts a nonblocking flush of the output buffer.
|
||||
*
|
||||
* Sends all buffered data from the socket's output buffer.
|
||||
* If the socket is not open, marks the session as dead and calls an
|
||||
* exception callback or sets a fatal error. If the socket cannot currently
|
||||
* accept data, polls for writable events and returns `SSH_AGAIN`.
|
||||
* On write errors, closes the socket and signals the error. Updates
|
||||
* byte counters on successful writes.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return `SSH_OK` if all data was sent; `SSH_AGAIN` if the operation should
|
||||
* be retried later; `SSH_ERROR` on fatal socket error.
|
||||
*/
|
||||
int ssh_socket_nonblocking_flush(ssh_socket s)
|
||||
{
|
||||
@@ -767,26 +909,79 @@ int ssh_socket_nonblocking_flush(ssh_socket s)
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Set the SSH socket write_wontblock flag.
|
||||
*
|
||||
* Marks the socket as ready for nonblocking writes (`write_wontblock = 1`).
|
||||
* Used by the poll system when POLLOUT becomes available.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*/
|
||||
void ssh_socket_set_write_wontblock(ssh_socket s)
|
||||
{
|
||||
s->write_wontblock = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Set the SSH socket read_wontblock flag.
|
||||
*
|
||||
* Marks the socket as ready for nonblocking reads (`read_wontblock = 1`).
|
||||
* Used by the poll system when POLLIN becomes available.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*/
|
||||
void ssh_socket_set_read_wontblock(ssh_socket s)
|
||||
{
|
||||
s->read_wontblock = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Set the SSH socket exception flag.
|
||||
*
|
||||
* Marks the socket as having an exception condition (`data_except = 1`).
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*/
|
||||
void ssh_socket_set_except(ssh_socket s)
|
||||
{
|
||||
s->data_except = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Check if SSH socket data is available for reading.
|
||||
*
|
||||
* Returns true if the socket is ready for nonblocking reads
|
||||
* (`read_wontblock` flag is set).
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return 1 if data is available, 0 otherwise.
|
||||
*/
|
||||
int ssh_socket_data_available(ssh_socket s)
|
||||
{
|
||||
return s->read_wontblock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Check if SSH socket is writable.
|
||||
*
|
||||
* Returns true if the socket is ready for nonblocking writes
|
||||
* (`write_wontblock` flag is set).
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return 1 if socket is writable, 0 otherwise.
|
||||
*/
|
||||
int ssh_socket_data_writable(ssh_socket s)
|
||||
{
|
||||
return s->write_wontblock;
|
||||
@@ -806,7 +1001,19 @@ int ssh_socket_buffered_write_bytes(ssh_socket s)
|
||||
return ssh_buffer_get_len(s->out_buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Get the current status of an SSH socket.
|
||||
*
|
||||
* Checks the input/output buffers and exception flag to determine socket
|
||||
* status: `SSH_READ_PENDING` if input data available, `SSH_WRITE_PENDING`
|
||||
* if output data pending, `SSH_CLOSED_ERROR` if exception occurred.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return Socket status flags.
|
||||
*/
|
||||
int ssh_socket_get_status(ssh_socket s)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -826,6 +1033,18 @@ int ssh_socket_get_status(ssh_socket s)
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Get SSH socket poll flags from the poll handle.
|
||||
*
|
||||
* Checks the poll handle events and returns `SSH_READ_PENDING` if POLLIN
|
||||
* is set, `SSH_WRITE_PENDING` if POLLOUT is set.
|
||||
*
|
||||
* @param[in] s The SSH socket.
|
||||
*
|
||||
* @return Socket status flags based on poll events.
|
||||
*/
|
||||
int ssh_socket_get_poll_flags(ssh_socket s)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -872,8 +1091,8 @@ int ssh_socket_set_blocking(socket_t fd)
|
||||
* @param host hostname or ip address to connect to.
|
||||
* @param port port number to connect to.
|
||||
* @param bind_addr address to bind to, or NULL for default.
|
||||
* @returns SSH_OK socket is being connected.
|
||||
* @returns SSH_ERROR error while connecting to remote host.
|
||||
* @returns `SSH_OK` socket is being connected.
|
||||
* @returns `SSH_ERROR` error while connecting to remote host.
|
||||
*/
|
||||
int ssh_socket_connect(ssh_socket s,
|
||||
const char *host,
|
||||
@@ -958,8 +1177,8 @@ ssh_execute_command(const char *command, socket_t in, socket_t out)
|
||||
* This call will always be nonblocking.
|
||||
* @param s socket to connect.
|
||||
* @param command Command to execute.
|
||||
* @returns SSH_OK socket is being connected.
|
||||
* @returns SSH_ERROR error while executing the command.
|
||||
* @returns `SSH_OK` socket is being connected.
|
||||
* @returns `SSH_ERROR` error while executing the command.
|
||||
*/
|
||||
int
|
||||
ssh_socket_connect_proxycommand(ssh_socket s, const char *command)
|
||||
|
||||
Reference in New Issue
Block a user