From 4feb0dd79db203d16fa0754042bc1b4536268188 Mon Sep 17 00:00:00 2001 From: Nikhil V Date: Sat, 6 Dec 2025 10:51:35 +0530 Subject: [PATCH] Improve doxygen documentation Signed-off-by: Nikhil V Reviewed-by: Jakub Jelen --- include/libssh/callbacks.h | 84 ++++---- include/libssh/ed25519.h | 12 +- include/libssh/libssh.h | 403 ------------------------------------- include/libssh/server.h | 13 +- src/channels.c | 248 ++++++++++++----------- src/connector.c | 79 +++++++- src/server.c | 353 ++++++++++++++++++++++++++++++-- src/session.c | 49 ++--- src/sftpserver.c | 242 +++++++++++++++++++++- src/socket.c | 301 +++++++++++++++++++++++---- 10 files changed, 1121 insertions(+), 663 deletions(-) diff --git a/include/libssh/callbacks.h b/include/libssh/callbacks.h index f507821c..13646aff 100644 --- a/include/libssh/callbacks.h +++ b/include/libssh/callbacks.h @@ -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 diff --git a/include/libssh/ed25519.h b/include/libssh/ed25519.h index 0a7d2951..a6bcdaf3 100644 --- a/include/libssh/ed25519.h +++ b/include/libssh/ed25519.h @@ -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]; diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 47acf6dd..6dff4d0e 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -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); diff --git a/include/libssh/server.h b/include/libssh/server.h index e437f292..94c2b10d 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -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); diff --git a/src/channels.c b/src/channels.c index 3979b66c..e9f57f88 100644 --- a/src/channels.c +++ b/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) diff --git a/src/connector.c b/src/connector.c index e2eec769..e8334804 100644 --- a/src/connector.c +++ b/src/connector.c @@ -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 * diff --git a/src/server.c b/src/server.c index f1126729..9c1f734b 100644 --- a/src/server.c +++ b/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) { diff --git a/src/session.c b/src/session.c index d76c0fb9..8f41e3f1 100644 --- a/src/session.c +++ b/src/session.c @@ -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. * diff --git a/src/sftpserver.c b/src/sftpserver.c index 98e30895..987d52a8 100644 --- a/src/sftpserver.c +++ b/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, diff --git a/src/socket.c b/src/socket.c index 3e96decc..5f44c5a4 100644 --- a/src/socket.c +++ b/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)