aboutsummaryrefslogtreecommitdiff
path: root/include/libssh
diff options
context:
space:
mode:
Diffstat (limited to 'include/libssh')
-rw-r--r--include/libssh/CMakeLists.txt7
-rw-r--r--include/libssh/agent.h8
-rw-r--r--include/libssh/auth.h8
-rw-r--r--include/libssh/bignum.h7
-rw-r--r--include/libssh/bind.h11
-rw-r--r--include/libssh/bind_config.h18
-rw-r--r--include/libssh/blf.h9
-rw-r--r--include/libssh/buffer.h14
-rw-r--r--include/libssh/callbacks.h103
-rw-r--r--include/libssh/chacha.h8
-rw-r--r--include/libssh/channels.h12
-rw-r--r--include/libssh/config.h8
-rw-r--r--include/libssh/config_parser.h19
-rw-r--r--include/libssh/crypto.h20
-rw-r--r--include/libssh/curve25519.h9
-rw-r--r--include/libssh/dh-gex.h9
-rw-r--r--include/libssh/dh.h22
-rw-r--r--include/libssh/ecdh.h9
-rw-r--r--include/libssh/ed25519.h12
-rw-r--r--include/libssh/fe25519.h8
-rw-r--r--include/libssh/ge25519.h8
-rw-r--r--include/libssh/gssapi.h8
-rw-r--r--include/libssh/kex.h15
-rw-r--r--include/libssh/keys.h18
-rw-r--r--include/libssh/knownhosts.h8
-rw-r--r--include/libssh/legacy.h26
-rw-r--r--include/libssh/libcrypto.h19
-rw-r--r--include/libssh/libgcrypt.h11
-rw-r--r--include/libssh/libmbedcrypto.h16
-rw-r--r--include/libssh/libssh.h129
-rw-r--r--include/libssh/libsshpp.hpp19
-rw-r--r--include/libssh/messages.h9
-rw-r--r--include/libssh/misc.h36
-rw-r--r--include/libssh/options.h13
-rw-r--r--include/libssh/packet.h13
-rw-r--r--include/libssh/pcap.h8
-rw-r--r--include/libssh/pki.h59
-rw-r--r--include/libssh/pki_priv.h35
-rw-r--r--include/libssh/poll.h8
-rw-r--r--include/libssh/poly1305.h8
-rw-r--r--include/libssh/priv.h49
-rw-r--r--include/libssh/sc25519.h8
-rw-r--r--include/libssh/scp.h8
-rw-r--r--include/libssh/server.h104
-rw-r--r--include/libssh/session.h71
-rw-r--r--include/libssh/sftp.h315
-rw-r--r--include/libssh/sftp_priv.h53
-rw-r--r--include/libssh/sftpserver.h73
-rw-r--r--include/libssh/socket.h5
-rw-r--r--include/libssh/string.h8
-rw-r--r--include/libssh/threads.h8
-rw-r--r--include/libssh/token.h13
-rw-r--r--include/libssh/wrapper.h63
53 files changed, 1318 insertions, 247 deletions
diff --git a/include/libssh/CMakeLists.txt b/include/libssh/CMakeLists.txt
index 83e7b9f8..93445680 100644
--- a/include/libssh/CMakeLists.txt
+++ b/include/libssh/CMakeLists.txt
@@ -20,6 +20,13 @@ if (WITH_SERVER)
${libssh_HDRS}
server.h
)
+
+ if (WITH_SFTP)
+ set(libssh_HDRS
+ ${libssh_HDRS}
+ sftpserver.h
+ )
+ endif (WITH_SFTP)
endif (WITH_SERVER)
install(
diff --git a/include/libssh/agent.h b/include/libssh/agent.h
index d4eefbbf..caf8d3e2 100644
--- a/include/libssh/agent.h
+++ b/include/libssh/agent.h
@@ -70,6 +70,10 @@
#define SSH_AGENT_RSA_SHA2_256 0x02
#define SSH_AGENT_RSA_SHA2_512 0x04
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ssh_agent_struct {
struct ssh_socket_struct *sock;
ssh_buffer ident;
@@ -77,7 +81,6 @@ struct ssh_agent_struct {
ssh_channel channel;
};
-#ifndef _WIN32
/* agent.c */
/**
* @brief Create a new ssh agent structure.
@@ -115,6 +118,9 @@ ssh_key ssh_agent_get_first_ident(struct ssh_session_struct *session,
ssh_string ssh_agent_sign_data(ssh_session session,
const ssh_key pubkey,
struct ssh_buffer_struct *data);
+
+#ifdef __cplusplus
+}
#endif
#endif /* __AGENT_H */
diff --git a/include/libssh/auth.h b/include/libssh/auth.h
index 90b377d4..b358b7a2 100644
--- a/include/libssh/auth.h
+++ b/include/libssh/auth.h
@@ -23,6 +23,10 @@
#include "config.h"
#include "libssh/callbacks.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
SSH_PACKET_CALLBACK(ssh_packet_userauth_banner);
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure);
SSH_PACKET_CALLBACK(ssh_packet_userauth_success);
@@ -100,4 +104,8 @@ enum ssh_auth_service_state_e {
SSH_AUTH_SERVICE_DENIED,
};
+#ifdef __cplusplus
+}
+#endif
+
#endif /* AUTH_H_ */
diff --git a/include/libssh/bignum.h b/include/libssh/bignum.h
index 726ed7b9..6b5dc1a2 100644
--- a/include/libssh/bignum.h
+++ b/include/libssh/bignum.h
@@ -25,9 +25,16 @@
#include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bignum ssh_make_string_bn(ssh_string string);
ssh_string ssh_make_bignum_string(bignum num);
void ssh_print_bignum(const char *which, const_bignum num);
+#ifdef __cplusplus
+}
+#endif
#endif /* BIGNUM_H_ */
diff --git a/include/libssh/bind.h b/include/libssh/bind.h
index 6b5f19dd..cd9199b6 100644
--- a/include/libssh/bind.h
+++ b/include/libssh/bind.h
@@ -25,6 +25,10 @@
#include "libssh/kex.h"
#include "libssh/session.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ssh_bind_struct {
struct ssh_common_struct common; /* stuff common to ssh_bind and ssh_session */
struct ssh_bind_callbacks_struct *bind_callbacks;
@@ -35,11 +39,9 @@ struct ssh_bind_struct {
char *wanted_methods[SSH_KEX_METHODS];
char *banner;
char *ecdsakey;
- char *dsakey;
char *rsakey;
char *ed25519key;
ssh_key ecdsa;
- ssh_key dsa;
ssh_key rsa;
ssh_key ed25519;
char *bindaddr;
@@ -50,10 +52,15 @@ struct ssh_bind_struct {
bool config_processed;
char *config_dir;
char *pubkey_accepted_key_types;
+ char* moduli_file;
+ int rsa_min_size;
};
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
*sshbind);
+#ifdef __cplusplus
+}
+#endif
#endif /* BIND_H_ */
diff --git a/include/libssh/bind_config.h b/include/libssh/bind_config.h
index cb68da89..5f2dccce 100644
--- a/include/libssh/bind_config.h
+++ b/include/libssh/bind_config.h
@@ -28,6 +28,10 @@
#include "libssh/server.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum ssh_bind_config_opcode_e {
/* Known but not allowed in Match block */
BIND_CFG_NOT_ALLOWED_IN_MATCH = -4,
@@ -61,4 +65,18 @@ enum ssh_bind_config_opcode_e {
*/
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename);
+/* @brief Parse configuration string and set the options to the given bind session
+ *
+ * @params[in] bind The ssh bind session
+ * @params[in] input Null terminated string containing the configuration
+ *
+ * @returns SSH_OK on successful parsing the configuration string,
+ * SSH_ERROR on error
+ */
+int ssh_bind_config_parse_string(ssh_bind bind, const char *input);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* BIND_CONFIG_H_ */
diff --git a/include/libssh/blf.h b/include/libssh/blf.h
index ce131e6b..201821a2 100644
--- a/include/libssh/blf.h
+++ b/include/libssh/blf.h
@@ -49,6 +49,10 @@
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
@@ -84,4 +88,9 @@ void ssh_blf_cbc_decrypt(ssh_blf_ctx *, uint8_t *, uint8_t *, uint32_t);
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t , uint16_t *);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _BLF_H */
diff --git a/include/libssh/buffer.h b/include/libssh/buffer.h
index cd2dea6a..1fce7b76 100644
--- a/include/libssh/buffer.h
+++ b/include/libssh/buffer.h
@@ -27,6 +27,10 @@
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void ssh_buffer_set_secure(ssh_buffer buffer);
int ssh_buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
int ssh_buffer_add_u8(ssh_buffer buffer, uint8_t data);
@@ -63,9 +67,9 @@ int ssh_buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
/* buffer_read_*() returns the number of bytes read, except for ssh strings */
-int ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
-int ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
-int ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
+uint32_t ssh_buffer_get_u8(ssh_buffer buffer, uint8_t *data);
+uint32_t ssh_buffer_get_u32(ssh_buffer buffer, uint32_t *data);
+uint32_t ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
@@ -74,4 +78,8 @@ ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* BUFFER_H_ */
diff --git a/include/libssh/callbacks.h b/include/libssh/callbacks.h
index 972314cb..29c1d391 100644
--- a/include/libssh/callbacks.h
+++ b/include/libssh/callbacks.h
@@ -27,6 +27,7 @@
#include <libssh/libssh.h>
#include <string.h>
+#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
@@ -56,7 +57,7 @@ typedef void (*ssh_callback_int) (int code, void *user);
* @returns number of bytes processed by the callee. The remaining bytes will
* be sent in the next callback message, when more data is available.
*/
-typedef int (*ssh_callback_data) (const void *data, size_t len, void *user);
+typedef size_t (*ssh_callback_data) (const void *data, size_t len, void *user);
typedef void (*ssh_callback_int_int) (int code, int errno_code, void *user);
@@ -81,9 +82,9 @@ typedef void (*ssh_log_callback) (ssh_session session, int priority,
*
* @param priority Priority of the log, the smaller being the more important.
*
- * @param function The function name calling the the logging fucntions.
+ * @param function The function name calling the logging functions.
*
- * @param message The actual message
+ * @param buffer The actual message
*
* @param userdata Userdata to be passed to the callback function.
*/
@@ -117,6 +118,8 @@ typedef void (*ssh_global_request_callback) (ssh_session session,
* sends back an X11 connection attempt. This is a client-side API
* @param session current session handler
* @param userdata Userdata to be passed to the callback function.
+ * @param originator_address IP address of the machine who sent the request
+ * @param originator_port port number of the machine who sent the request
* @returns a valid ssh_channel handle if the request is to be allowed
* @returns NULL if the request should not be allowed
* @warning The channel pointer returned by this callback must be closed by the application.
@@ -137,6 +140,26 @@ typedef ssh_channel (*ssh_channel_open_request_auth_agent_callback) (ssh_session
void *userdata);
/**
+ * @brief Handles an SSH new channel open "forwarded-tcpip" request. This
+ * happens when the server forwards an incoming TCP connection on a port it was
+ * previously requested to listen on. This is a client-side API
+ * @param session current session handler
+ * @param destination_address the address that the TCP connection connected to
+ * @param destination_port the port that the TCP connection connected to
+ * @param originator_address the originator IP address
+ * @param originator_port the originator port
+ * @param userdata Userdata to be passed to the callback function.
+ * @returns a valid ssh_channel handle if the request is to be allowed
+ * @returns NULL if the request should not be allowed
+ * @warning The channel pointer returned by this callback must be closed by the
+ * application.
+ */
+typedef ssh_channel (*ssh_channel_open_request_forwarded_tcpip_callback) (ssh_session session,
+ const char *destination_address, int destination_port,
+ const char *originator_address, int originator_port,
+ void *userdata);
+
+/**
* The structure to replace libssh functions with appropriate callbacks.
*/
struct ssh_callbacks_struct {
@@ -169,6 +192,11 @@ struct ssh_callbacks_struct {
/** This function will be called when an incoming "auth-agent" request is received.
*/
ssh_channel_open_request_auth_agent_callback channel_open_request_auth_agent_function;
+ /**
+ * This function will be called when an incoming "forwarded-tcpip"
+ * request is received.
+ */
+ ssh_channel_open_request_forwarded_tcpip_callback channel_open_request_forwarded_tcpip_function;
};
typedef struct ssh_callbacks_struct *ssh_callbacks;
@@ -221,8 +249,8 @@ typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *us
* @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.
+ * 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.
@@ -268,11 +296,11 @@ typedef ssh_string (*ssh_gssapi_select_oid_callback) (ssh_session session, const
int n_oid, ssh_string *oids, void *userdata);
/*
- * @brief handle the negociation of a security context, server side.
+ * @brief handle the negotiation of a security context, server side.
* @param session current session handler
* @param[in] input_token input token provided by client
* @param[out] output_token output of the gssapi accept_sec_context method,
- * NULL after completion.
+ * NULL after completion.
* @returns SSH_OK if the token was generated correctly or accept_sec_context
* returned GSS_S_COMPLETE
* @returns SSH_ERROR in case of error
@@ -397,7 +425,7 @@ struct ssh_socket_callbacks_struct {
*/
ssh_callback_int_int exception;
/** This function is called when the ssh_socket_connect was used on the socket
- * on nonblocking state, and the connection successed.
+ * on nonblocking state, and the connection succeeded.
*/
ssh_callback_int_int connected;
};
@@ -625,6 +653,7 @@ typedef void (*ssh_channel_signal_callback) (ssh_session session,
* @brief SSH channel exit status callback. Called when a channel has received an exit status
* @param session Current session handler
* @param channel the actual channel
+ * @param exit_status Exit status of the ran command
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
@@ -637,7 +666,7 @@ typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
- * @param core a boolean telling wether a core has been dumped or not
+ * @param core a boolean telling whether a core has been dumped or not
* @param errmsg the description of the exception
* @param lang the language of the description (format: RFC 3066)
* @param userdata Userdata to be passed to the callback function.
@@ -652,12 +681,13 @@ typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
/**
* @brief SSH channel PTY request from a client.
+ * @param session the session
* @param channel the channel
* @param term The type of terminal emulation
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
- * @param pxheight height of the terminal, in pixels
+ * @param pwheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
@@ -671,6 +701,7 @@ typedef int (*ssh_channel_pty_request_callback) (ssh_session session,
/**
* @brief SSH channel Shell request from a client.
+ * @param session the session
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the shell request is accepted
@@ -683,6 +714,7 @@ typedef int (*ssh_channel_shell_request_callback) (ssh_session session,
* @brief SSH auth-agent-request from the client. This request is
* sent by a client when agent forwarding is available.
* Server is free to ignore this callback, no answer is expected.
+ * @param session the session
* @param channel the channel
* @param userdata Userdata to be passed to the callback function.
*/
@@ -694,7 +726,12 @@ typedef void (*ssh_channel_auth_agent_req_callback) (ssh_session session,
* @brief SSH X11 request from the client. This request is
* sent by a client when X11 forwarding is requested(and available).
* Server is free to ignore this callback, no answer is expected.
+ * @param session the session
* @param channel the channel
+ * @param single_connection If true, only one channel should be forwarded
+ * @param auth_protocol The X11 authentication method to be used
+ * @param auth_cookie Authentication cookie encoded hexadecimal
+ * @param screen_number Screen number
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
@@ -706,11 +743,12 @@ typedef void (*ssh_channel_x11_req_callback) (ssh_session session,
void *userdata);
/**
* @brief SSH channel PTY windows change (terminal size) from a client.
+ * @param session the session
* @param channel the channel
* @param width width of the terminal, in characters
* @param height height of the terminal, in characters
* @param pxwidth width of the terminal, in pixels
- * @param pxheight height of the terminal, in pixels
+ * @param pwheight height of the terminal, in pixels
* @param userdata Userdata to be passed to the callback function.
* @returns 0 if the pty request is accepted
* @returns -1 if the request is denied
@@ -723,6 +761,7 @@ typedef int (*ssh_channel_pty_window_change_callback) (ssh_session session,
/**
* @brief SSH channel Exec request from a client.
+ * @param session the session
* @param channel the channel
* @param command the shell command to be executed
* @param userdata Userdata to be passed to the callback function.
@@ -736,6 +775,7 @@ typedef int (*ssh_channel_exec_request_callback) (ssh_session session,
/**
* @brief SSH channel environment request from a client.
+ * @param session the session
* @param channel the channel
* @param env_name name of the environment value to be set
* @param env_value value of the environment value to be set
@@ -752,6 +792,7 @@ typedef int (*ssh_channel_env_request_callback) (ssh_session session,
void *userdata);
/**
* @brief SSH channel subsystem request from a client.
+ * @param session the session
* @param channel the channel
* @param subsystem the subsystem required
* @param userdata Userdata to be passed to the callback function.
@@ -766,6 +807,8 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
/**
* @brief SSH channel write will not block (flow control).
*
+ * @param session the session
+ *
* @param channel the channel
*
* @param[in] bytes size of the remote window in bytes. Writing as much data
@@ -777,9 +820,31 @@ typedef int (*ssh_channel_subsystem_request_callback) (ssh_session session,
*/
typedef int (*ssh_channel_write_wontblock_callback) (ssh_session session,
ssh_channel channel,
- size_t bytes,
+ uint32_t bytes,
void *userdata);
+/**
+ * @brief SSH channel open callback. Called when a channel open succeeds or fails.
+ * @param session Current session handler
+ * @param channel the actual channel
+ * @param is_success is 1 when the open succeeds, and 0 otherwise.
+ * @param userdata Userdata to be passed to the callback function.
+ */
+typedef void (*ssh_channel_open_resp_callback) (ssh_session session,
+ ssh_channel channel,
+ bool is_success,
+ void *userdata);
+
+/**
+ * @brief SSH channel request response callback. Called when a response to the pending request is received.
+ * @param session Current session handler
+ * @param channel the actual channel
+ * @param userdata Userdata to be passed to the callback function.
+ */
+typedef void (*ssh_channel_request_resp_callback) (ssh_session session,
+ ssh_channel channel,
+ void *userdata);
+
struct ssh_channel_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
@@ -847,6 +912,14 @@ struct ssh_channel_callbacks_struct {
* not to block.
*/
ssh_channel_write_wontblock_callback channel_write_wontblock_function;
+ /**
+ * This functions will be called when the channel has received a channel open confirmation or failure.
+ */
+ ssh_channel_open_resp_callback channel_open_response_function;
+ /**
+ * This functions will be called when the channel has received the response to the pending request.
+ */
+ ssh_channel_request_resp_callback channel_request_response_function;
};
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
@@ -917,7 +990,7 @@ LIBSSH_API int ssh_remove_channel_callbacks(ssh_channel channel,
/** @} */
-/** @group libssh_threads
+/** @addtogroup libssh_threads
* @{
*/
@@ -983,13 +1056,14 @@ LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_pthread(void);
* @see ssh_threads_set_callbacks
*/
LIBSSH_API struct ssh_threads_callbacks_struct *ssh_threads_get_noop(void);
+/** @} */
/**
* @brief Set the logging callback function.
*
* @param[in] cb The callback to set.
*
- * @return 0 on success, < 0 on errror.
+ * @return 0 on success, < 0 on error.
*/
LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
@@ -1000,7 +1074,6 @@ LIBSSH_API int ssh_set_log_callback(ssh_logging_callback cb);
*/
LIBSSH_API ssh_logging_callback ssh_get_log_callback(void);
-/** @} */
#ifdef __cplusplus
}
#endif
diff --git a/include/libssh/chacha.h b/include/libssh/chacha.h
index 867f532d..ab3fe492 100644
--- a/include/libssh/chacha.h
+++ b/include/libssh/chacha.h
@@ -18,6 +18,10 @@ struct chacha_ctx {
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)))
@@ -37,4 +41,8 @@ void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
#endif
;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* CHACHA_H */
diff --git a/include/libssh/channels.h b/include/libssh/channels.h
index bbabcfd1..cb2bea43 100644
--- a/include/libssh/channels.h
+++ b/include/libssh/channels.h
@@ -22,6 +22,10 @@
#define CHANNELS_H_
#include "libssh/priv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** @internal
* Describes the different possible states in a
* outgoing (client) channel request
@@ -35,7 +39,7 @@ enum ssh_channel_request_state_e {
SSH_CHANNEL_REQ_STATE_ACCEPTED,
/** A request has been replied and refused */
SSH_CHANNEL_REQ_STATE_DENIED,
- /** A request has been replied and an error happend */
+ /** A request has been replied and an error happened */
SSH_CHANNEL_REQ_STATE_ERROR
};
@@ -98,7 +102,7 @@ SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data);
int channel_default_bufferize(ssh_channel channel,
- void *data, size_t len,
+ void *data, uint32_t len,
bool is_stderr);
int ssh_channel_flush(ssh_channel channel);
uint32_t ssh_channel_new_id(ssh_session session);
@@ -109,4 +113,8 @@ int ssh_global_request(ssh_session session,
ssh_buffer buffer,
int reply);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* CHANNELS_H_ */
diff --git a/include/libssh/config.h b/include/libssh/config.h
index f2b9b57c..4f8a9b6f 100644
--- a/include/libssh/config.h
+++ b/include/libssh/config.h
@@ -42,7 +42,6 @@ enum ssh_config_opcode_e {
SOC_MACS,
SOC_COMPRESSION,
SOC_TIMEOUT,
- SOC_PROTOCOL,
SOC_STRICTHOSTKEYCHECK,
SOC_KNOWNHOSTS,
SOC_PROXYCOMMAND,
@@ -60,8 +59,13 @@ enum ssh_config_opcode_e {
SOC_KBDINTERACTIVEAUTHENTICATION,
SOC_PASSWORDAUTHENTICATION,
SOC_PUBKEYAUTHENTICATION,
- SOC_PUBKEYACCEPTEDTYPES,
+ SOC_PUBKEYACCEPTEDKEYTYPES,
SOC_REKEYLIMIT,
+ SOC_IDENTITYAGENT,
+ SOC_IDENTITIESONLY,
+ SOC_CONTROLMASTER,
+ SOC_CONTROLPATH,
+ SOC_CERTIFICATE,
SOC_MAX /* Keep this one last in the list */
};
diff --git a/include/libssh/config_parser.h b/include/libssh/config_parser.h
index e974917c..4648614c 100644
--- a/include/libssh/config_parser.h
+++ b/include/libssh/config_parser.h
@@ -26,6 +26,12 @@
#ifndef CONFIG_PARSER_H_
#define CONFIG_PARSER_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
char *ssh_config_get_cmd(char **str);
char *ssh_config_get_token(char **str);
@@ -45,13 +51,20 @@ int ssh_config_get_yesno(char **str, int notfound);
* be stored or NULL if we do not care about the result.
* @param[out] port Pointer to the location, where the new port will
* be stored or NULL if we do not care about the result.
+ * @param[in] ignore_port Set to true if we should not attempt to parse
+ * port number.
*
* @returns SSH_OK if the provided string is in format of SSH URI,
* SSH_ERROR on failure
*/
int ssh_config_parse_uri(const char *tok,
- char **username,
- char **hostname,
- char **port);
+ char **username,
+ char **hostname,
+ char **port,
+ bool ignore_port);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* LIBSSH_CONFIG_H_ */
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index 67d98392..32016827 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -111,7 +111,11 @@ struct ssh_crypto_struct {
#endif /* WITH_GEX */
#ifdef HAVE_ECDH
#ifdef HAVE_OPENSSL_ECC
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
EC_KEY *ecdh_privkey;
+#else
+ EVP_PKEY *ecdh_privkey;
+#endif /* OPENSSL_VERSION_NUMBER */
#elif defined HAVE_GCRYPT_ECC
gcry_sexp_t ecdh_privkey;
#elif defined HAVE_LIBMBEDCRYPTO
@@ -126,8 +130,9 @@ struct ssh_crypto_struct {
ssh_curve25519_pubkey curve25519_server_pubkey;
#endif
ssh_string dh_server_signature; /* information used by dh_handshake. */
- size_t digest_len; /* len of the two fields below */
+ size_t session_id_len;
unsigned char *session_id;
+ size_t digest_len; /* len of the secret hash */
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
unsigned char *encryptIV;
unsigned char *decryptIV;
@@ -207,12 +212,23 @@ struct ssh_cipher_struct {
void (*cleanup)(struct ssh_cipher_struct *cipher);
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
const struct ssh_cipher_struct *ssh_get_chacha20poly1305_cipher(void);
int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,
- int key_type, unsigned char *output,
+ uint8_t key_type, unsigned char *output,
size_t requested_len);
int secure_memcmp(const void *s1, const void *s2, size_t n);
+#if defined(HAVE_LIBCRYPTO) && !defined(WITH_PKCS11_PROVIDER)
+ENGINE *pki_get_engine(void);
+#endif /* HAVE_LIBCRYPTO */
+
+#ifdef __cplusplus
+}
+#endif
#endif /* _CRYPTO_H_ */
diff --git a/include/libssh/curve25519.h b/include/libssh/curve25519.h
index f0cc6348..a55f52c7 100644
--- a/include/libssh/curve25519.h
+++ b/include/libssh/curve25519.h
@@ -33,6 +33,10 @@
#define crypto_scalarmult crypto_scalarmult_curve25519
#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define CURVE25519_PUBKEY_SIZE 32
#define CURVE25519_PRIVKEY_SIZE 32
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
@@ -48,9 +52,14 @@ typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
int ssh_client_curve25519_init(ssh_session session);
+void ssh_client_curve25519_remove_callbacks(ssh_session session);
#ifdef WITH_SERVER
void ssh_server_curve25519_init(ssh_session session);
#endif /* WITH_SERVER */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* CURVE25519_H_ */
diff --git a/include/libssh/dh-gex.h b/include/libssh/dh-gex.h
index 4fc23d82..0f547e37 100644
--- a/include/libssh/dh-gex.h
+++ b/include/libssh/dh-gex.h
@@ -23,10 +23,19 @@
#ifndef SRC_DH_GEX_H_
#define SRC_DH_GEX_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ssh_client_dhgex_init(ssh_session session);
+void ssh_client_dhgex_remove_callbacks(ssh_session session);
#ifdef WITH_SERVER
void ssh_server_dhgex_init(ssh_session session);
#endif /* WITH_SERVER */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* SRC_DH_GEX_H_ */
diff --git a/include/libssh/dh.h b/include/libssh/dh.h
index 390b30da..34c4a7ed 100644
--- a/include/libssh/dh.h
+++ b/include/libssh/dh.h
@@ -30,20 +30,34 @@ struct dh_ctx;
#define DH_CLIENT_KEYPAIR 0
#define DH_SERVER_KEYPAIR 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* functions implemented by crypto backends */
int ssh_dh_init_common(struct ssh_crypto_struct *crypto);
void ssh_dh_cleanup(struct ssh_crypto_struct *crypto);
+#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
int ssh_dh_get_parameters(struct dh_ctx *ctx,
const_bignum *modulus, const_bignum *generator);
+#else
+int ssh_dh_get_parameters(struct dh_ctx *ctx,
+ bignum *modulus, bignum *generator);
+#endif /* OPENSSL_VERSION_NUMBER */
int ssh_dh_set_parameters(struct dh_ctx *ctx,
const bignum modulus, const bignum generator);
int ssh_dh_keypair_gen_keys(struct dh_ctx *ctx, int peer);
+#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
const_bignum *priv, const_bignum *pub);
+#else
+int ssh_dh_keypair_get_keys(struct dh_ctx *ctx, int peer,
+ bignum *priv, bignum *pub);
+#endif /* OPENSSL_VERSION_NUMBER */
int ssh_dh_keypair_set_keys(struct dh_ctx *ctx, int peer,
- const bignum priv, const bignum pub);
+ bignum priv, bignum pub);
int ssh_dh_compute_shared_secret(struct dh_ctx *ctx, int local, int remote,
bignum *dest);
@@ -63,8 +77,10 @@ int ssh_dh_get_current_server_publickey_blob(ssh_session session,
ssh_key ssh_dh_get_next_server_publickey(ssh_session session);
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
ssh_string *pubkey_blob);
+int dh_handshake(ssh_session session);
int ssh_client_dh_init(ssh_session session);
+void ssh_client_dh_remove_callbacks(ssh_session session);
#ifdef WITH_SERVER
void ssh_server_dh_init(ssh_session session);
#endif /* WITH_SERVER */
@@ -72,4 +88,8 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet);
int ssh_fallback_group(uint32_t pmax, bignum *p, bignum *g);
bool ssh_dh_is_known_group(bignum modulus, bignum generator);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* DH_H_ */
diff --git a/include/libssh/ecdh.h b/include/libssh/ecdh.h
index 17fe02e7..4c4c54eb 100644
--- a/include/libssh/ecdh.h
+++ b/include/libssh/ecdh.h
@@ -42,9 +42,14 @@
#define HAVE_ECDH 1
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern struct ssh_packet_callbacks_struct ssh_ecdh_client_callbacks;
/* Backend-specific functions. */
int ssh_client_ecdh_init(ssh_session session);
+void ssh_client_ecdh_remove_callbacks(ssh_session session);
int ecdh_build_k(ssh_session session);
#ifdef WITH_SERVER
@@ -53,4 +58,8 @@ void ssh_server_ecdh_init(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init);
#endif /* WITH_SERVER */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ECDH_H_ */
diff --git a/include/libssh/ed25519.h b/include/libssh/ed25519.h
index 8a3263c8..72a86c0b 100644
--- a/include/libssh/ed25519.h
+++ b/include/libssh/ed25519.h
@@ -24,10 +24,10 @@
/**
* @defgroup ed25519 ed25519 API
- * @internal
* @brief API for DJB's ed25519
*
- * @{ */
+ * @{
+ */
#define ED25519_PK_LEN 32
#define ED25519_SK_LEN 64
@@ -37,6 +37,10 @@ typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** @internal
* @brief generate an ed25519 key pair
* @param[out] pk generated public key
@@ -76,4 +80,8 @@ int crypto_sign_ed25519_open(
const ed25519_pubkey pk);
/** @} */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ED25519_H_ */
diff --git a/include/libssh/fe25519.h b/include/libssh/fe25519.h
index 438d85db..0dfb0613 100644
--- a/include/libssh/fe25519.h
+++ b/include/libssh/fe25519.h
@@ -33,6 +33,10 @@ typedef struct {
uint32_t v[32];
} fe25519;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void fe25519_freeze(fe25519 *r);
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
@@ -65,4 +69,8 @@ void fe25519_invert(fe25519 *r, const fe25519 *x);
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/libssh/ge25519.h b/include/libssh/ge25519.h
index 329bd042..480f29dc 100644
--- a/include/libssh/ge25519.h
+++ b/include/libssh/ge25519.h
@@ -28,6 +28,10 @@ typedef struct
fe25519 t;
} ge25519;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern const ge25519 ge25519_base;
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
@@ -40,4 +44,8 @@ void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/libssh/gssapi.h b/include/libssh/gssapi.h
index ccd83664..b0c74c73 100644
--- a/include/libssh/gssapi.h
+++ b/include/libssh/gssapi.h
@@ -29,6 +29,10 @@
typedef struct ssh_gssapi_struct *ssh_gssapi;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef WITH_SERVER
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids);
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server);
@@ -42,4 +46,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response);
int ssh_gssapi_auth_mic(ssh_session session);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GSSAPI_H */
diff --git a/include/libssh/kex.h b/include/libssh/kex.h
index 3a1f4a6f..4a2ecb99 100644
--- a/include/libssh/kex.h
+++ b/include/libssh/kex.h
@@ -31,15 +31,24 @@ struct ssh_kex_struct {
char *methods[SSH_KEX_METHODS];
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
-int ssh_send_kex(ssh_session session, int server_kex);
+int ssh_send_kex(ssh_session session);
void ssh_list_kex(struct ssh_kex_struct *kex);
int ssh_set_client_kex(ssh_session session);
+int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex);
int ssh_kex_select_methods(ssh_session session);
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list);
+char *ssh_add_to_default_algos(enum ssh_kex_types_e algo, const char *list);
+char *ssh_remove_from_default_algos(enum ssh_kex_types_e algo,
+ const char *list);
+char *ssh_prefix_default_algos(enum ssh_kex_types_e algo, const char *list);
char **ssh_space_tokenize(const char *chain);
int ssh_get_kex1(ssh_session session);
char *ssh_find_matching(const char *in_d, const char *what_d);
@@ -56,4 +65,8 @@ int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
int ssh_hashbufout_add_cookie(ssh_session session);
int ssh_generate_session_keys(ssh_session session);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* KEX_H_ */
diff --git a/include/libssh/keys.h b/include/libssh/keys.h
index 7b138612..1379539e 100644
--- a/include/libssh/keys.h
+++ b/include/libssh/keys.h
@@ -29,34 +29,36 @@ struct ssh_public_key_struct {
int type;
const char *type_c; /* Don't free it ! it is static */
#if defined(HAVE_LIBGCRYPT)
- gcry_sexp_t dsa_pub;
gcry_sexp_t rsa_pub;
#elif defined(HAVE_LIBCRYPTO)
- DSA *dsa_pub;
- RSA *rsa_pub;
+ EVP_PKEY *key_pub;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa_pub;
- void *dsa_pub;
#endif
};
struct ssh_private_key_struct {
int type;
#if defined(HAVE_LIBGCRYPT)
- gcry_sexp_t dsa_priv;
gcry_sexp_t rsa_priv;
#elif defined(HAVE_LIBCRYPTO)
- DSA *dsa_priv;
- RSA *rsa_priv;
+ EVP_PKEY *key_priv;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa_priv;
- void *dsa_priv;
#endif
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
const char *ssh_type_to_char(int type);
int ssh_type_from_name(const char *name);
ssh_public_key publickey_from_string(ssh_session session, ssh_string pubkey_s);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* KEYS_H_ */
diff --git a/include/libssh/knownhosts.h b/include/libssh/knownhosts.h
index 44e434c0..b50018cd 100644
--- a/include/libssh/knownhosts.h
+++ b/include/libssh/knownhosts.h
@@ -22,6 +22,10 @@
#ifndef SSH_KNOWNHOSTS_H_
#define SSH_KNOWNHOSTS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
char *ssh_known_hosts_get_algorithms_names(ssh_session session);
enum ssh_known_hosts_e
@@ -29,4 +33,8 @@ ssh_session_get_known_hosts_entry_file(ssh_session session,
const char *filename,
struct ssh_knownhosts_entry **pentry);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* SSH_KNOWNHOSTS_H_ */
diff --git a/include/libssh/legacy.h b/include/libssh/legacy.h
index 911173ee..38bef4da 100644
--- a/include/libssh/legacy.h
+++ b/include/libssh/legacy.h
@@ -31,6 +31,10 @@
typedef struct ssh_private_key_struct* ssh_private_key;
typedef struct ssh_public_key_struct* ssh_public_key;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
LIBSSH_API int ssh_auth_list(ssh_session session);
LIBSSH_API int ssh_userauth_offer_pubkey(ssh_session session, const char *username, int type, ssh_string publickey);
LIBSSH_API int ssh_userauth_pubkey(ssh_session session, const char *username, ssh_string publickey, ssh_private_key privatekey);
@@ -88,19 +92,19 @@ SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
-LIBSSH_API void privatekey_free(ssh_private_key prv);
-LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
+SSH_DEPRECATED LIBSSH_API void privatekey_free(ssh_private_key prv);
+SSH_DEPRECATED LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
int type, const char *passphrase);
-LIBSSH_API void publickey_free(ssh_public_key key);
-LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
+SSH_DEPRECATED LIBSSH_API void publickey_free(ssh_public_key key);
+SSH_DEPRECATED LIBSSH_API int ssh_publickey_to_file(ssh_session session, const char *file,
ssh_string pubkey, int type);
-LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
+SSH_DEPRECATED LIBSSH_API ssh_string publickey_from_file(ssh_session session, const char *filename,
int *type);
-LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
-LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
-LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
+SSH_DEPRECATED LIBSSH_API ssh_public_key publickey_from_privatekey(ssh_private_key prv);
+SSH_DEPRECATED LIBSSH_API ssh_string publickey_to_string(ssh_public_key key);
+SSH_DEPRECATED LIBSSH_API int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
ssh_string *publickey, int *type);
-LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
+SSH_DEPRECATED LIBSSH_API enum ssh_keytypes_e ssh_privatekey_type(ssh_private_key privatekey);
LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
@@ -117,4 +121,8 @@ SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* LEGACY_H_ */
diff --git a/include/libssh/libcrypto.h b/include/libssh/libcrypto.h
index 403c2d22..2f6bdc0a 100644
--- a/include/libssh/libcrypto.h
+++ b/include/libssh/libcrypto.h
@@ -25,13 +25,14 @@
#ifdef HAVE_LIBCRYPTO
-#include <openssl/dsa.h>
+#include "libssh/libssh.h"
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
+#include <openssl/ec.h>
typedef EVP_MD_CTX* SHACTX;
typedef EVP_MD_CTX* SHA256CTX;
@@ -39,11 +40,6 @@ typedef EVP_MD_CTX* SHA384CTX;
typedef EVP_MD_CTX* SHA512CTX;
typedef EVP_MD_CTX* MD5CTX;
typedef EVP_MD_CTX* HMACCTX;
-#ifdef HAVE_ECC
-typedef EVP_MD_CTX *EVPCTX;
-#else
-typedef void *EVPCTX;
-#endif
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
@@ -58,8 +54,15 @@ typedef void *EVPCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
#endif
+/* Use ssh_crypto_free() to release memory allocated by bignum_bn2dec(),
+ bignum_bn2hex() and other functions that use crypto-library functions that
+ are documented to allocate memory that needs to be de-allocate with
+ OPENSSL_free. */
+#define ssh_crypto_free(x) OPENSSL_free(x)
+
#include <openssl/bn.h>
#include <openssl/opensslv.h>
+
typedef BIGNUM* bignum;
typedef const BIGNUM* const_bignum;
typedef BN_CTX* bignum_CTX;
@@ -110,10 +113,14 @@ typedef BN_CTX* bignum_CTX;
/* Returns true if the OpenSSL is operating in FIPS mode */
#ifdef HAVE_OPENSSL_FIPS_MODE
#define ssh_fips_mode() (FIPS_mode() != 0)
+#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
+#define ssh_fips_mode() EVP_default_properties_is_fips_enabled(NULL)
#else
#define ssh_fips_mode() false
#endif
+ssh_string pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p);
+int pki_key_ecgroup_name_to_nid(const char *group);
#endif /* HAVE_LIBCRYPTO */
#endif /* LIBCRYPTO_H_ */
diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h
index 347d851b..a8044545 100644
--- a/include/libssh/libgcrypt.h
+++ b/include/libssh/libgcrypt.h
@@ -32,7 +32,6 @@ typedef gcry_md_hd_t SHA384CTX;
typedef gcry_md_hd_t SHA512CTX;
typedef gcry_md_hd_t MD5CTX;
typedef gcry_md_hd_t HMACCTX;
-typedef gcry_md_hd_t EVPCTX;
#define SHA_DIGEST_LENGTH 20
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
#define MD5_DIGEST_LEN 16
@@ -49,6 +48,8 @@ typedef gcry_md_hd_t EVPCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
+#define ssh_crypto_free(x) gcry_free(x)
+
typedef gcry_mpi_t bignum;
typedef const struct gcry_mpi *const_bignum;
typedef void* bignum_CTX;
@@ -104,6 +105,10 @@ int ssh_gcry_rand_range(bignum rnd, bignum max);
} while(0)
/* Helper functions for data conversions. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Extract an MPI from the given s-expression SEXP named NAME which is
encoded using INFORMAT and store it in a newly allocated ssh_string
encoded using OUTFORMAT. */
@@ -114,6 +119,10 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
#define ssh_fips_mode() false
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_LIBGCRYPT */
#endif /* LIBGCRYPT_H_ */
diff --git a/include/libssh/libmbedcrypto.h b/include/libssh/libmbedcrypto.h
index fe53019b..918fe293 100644
--- a/include/libssh/libmbedcrypto.h
+++ b/include/libssh/libmbedcrypto.h
@@ -34,6 +34,7 @@
#include <mbedtls/cipher.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/platform.h>
typedef mbedtls_md_context_t *SHACTX;
typedef mbedtls_md_context_t *SHA256CTX;
@@ -41,7 +42,6 @@ typedef mbedtls_md_context_t *SHA384CTX;
typedef mbedtls_md_context_t *SHA512CTX;
typedef mbedtls_md_context_t *MD5CTX;
typedef mbedtls_md_context_t *HMACCTX;
-typedef mbedtls_md_context_t *EVPCTX;
#define SHA_DIGEST_LENGTH 20
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
@@ -59,6 +59,8 @@ typedef mbedtls_md_context_t *EVPCTX;
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
+#define ssh_crypto_free(x) mbedtls_free(x)
+
typedef mbedtls_mpi *bignum;
typedef const mbedtls_mpi *const_bignum;
typedef void* bignum_CTX;
@@ -73,9 +75,13 @@ struct mbedtls_ecdsa_sig {
bignum s;
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bignum ssh_mbedcry_bn_new(void);
void ssh_mbedcry_bn_free(bignum num);
-unsigned char *ssh_mbedcry_bn2num(const_bignum num, int radix);
+char *ssh_mbedcry_bn2num(const_bignum num, int radix);
int ssh_mbedcry_rand(bignum rnd, int bits, int top, int bottom);
int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
int ssh_mbedcry_rand_range(bignum dest, bignum max);
@@ -101,7 +107,7 @@ int ssh_mbedcry_hex2bn(bignum *dest, char *data);
} while(0)
#define bignum_bn2dec(num) ssh_mbedcry_bn2num(num, 10)
#define bignum_dec2bn(data, bn) mbedtls_mpi_read_string(bn, 10, data)
-#define bignum_bn2hex(num, dest) (*dest)=ssh_mbedcry_bn2num(num, 16)
+#define bignum_bn2hex(num, dest) (*dest)=(unsigned char *)ssh_mbedcry_bn2num(num, 16)
#define bignum_hex2bn(data, dest) ssh_mbedcry_hex2bn(dest, data)
#define bignum_rand(rnd, bits) ssh_mbedcry_rand((rnd), (bits), 0, 1)
#define bignum_rand_range(rnd, max) ssh_mbedcry_rand_range(rnd, max)
@@ -136,5 +142,9 @@ ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
#define ssh_fips_mode() false
+#ifdef __cplusplus
+}
+#endif
+
#endif /* HAVE_LIBMBEDCRYPTO */
#endif /* LIBMBEDCRYPTO_H_ */
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h
index 4f401056..13f1b812 100644
--- a/include/libssh/libssh.h
+++ b/include/libssh/libssh.h
@@ -1,7 +1,7 @@
/*
* This file is part of the SSH Library
*
- * Copyright (c) 2003-2021 by Aris Adamantiadis and the libssh team
+ * Copyright (c) 2003-2024 by Aris Adamantiadis and the libssh team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -49,17 +49,14 @@
#endif
#endif
+#include <stdarg.h>
+#include <stdint.h>
+#include <inttypes.h>
+
#ifdef _MSC_VER
- /* Visual Studio hasn't inttypes.h so it doesn't know uint32_t */
- typedef int int32_t;
- typedef unsigned int uint32_t;
- typedef unsigned short uint16_t;
- typedef unsigned char uint8_t;
- typedef unsigned long long uint64_t;
typedef int mode_t;
#else /* _MSC_VER */
#include <unistd.h>
- #include <inttypes.h>
#include <sys/types.h>
#endif /* _MSC_VER */
@@ -80,7 +77,7 @@
#define PRINTF_ATTRIBUTE(a,b)
#endif /* __GNUC__ */
-#ifdef __GNUC__
+#if !defined(SSH_SUPPRESS_DEPRECATED) && defined(__GNUC__)
#define SSH_DEPRECATED __attribute__ ((deprecated))
#else
#define SSH_DEPRECATED
@@ -194,7 +191,8 @@ enum ssh_global_requests_e {
SSH_GLOBAL_REQUEST_UNKNOWN=0,
SSH_GLOBAL_REQUEST_TCPIP_FORWARD,
SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD,
- SSH_GLOBAL_REQUEST_KEEPALIVE
+ SSH_GLOBAL_REQUEST_KEEPALIVE,
+ SSH_GLOBAL_REQUEST_NO_MORE_SESSIONS
};
enum ssh_publickey_state_e {
@@ -275,12 +273,12 @@ enum ssh_error_types_e {
/* some types for keys */
enum ssh_keytypes_e{
SSH_KEYTYPE_UNKNOWN=0,
- SSH_KEYTYPE_DSS=1,
+ SSH_KEYTYPE_DSS=1, /* deprecated */
SSH_KEYTYPE_RSA,
SSH_KEYTYPE_RSA1,
SSH_KEYTYPE_ECDSA, /* deprecated */
SSH_KEYTYPE_ED25519,
- SSH_KEYTYPE_DSS_CERT01,
+ SSH_KEYTYPE_DSS_CERT01, /* deprecated */
SSH_KEYTYPE_RSA_CERT01,
SSH_KEYTYPE_ECDSA_P256,
SSH_KEYTYPE_ECDSA_P384,
@@ -297,7 +295,8 @@ enum ssh_keytypes_e{
enum ssh_keycmp_e {
SSH_KEY_CMP_PUBLIC = 0,
- SSH_KEY_CMP_PRIVATE
+ SSH_KEY_CMP_PRIVATE = 1,
+ SSH_KEY_CMP_CERTIFICATE = 2,
};
#define SSH_ADDRSTRLEN 46
@@ -326,16 +325,16 @@ enum {
/** No logging at all
*/
SSH_LOG_NOLOG=0,
- /** Only warnings
+ /** Only unrecoverable errors
*/
SSH_LOG_WARNING,
- /** High level protocol information
+ /** Information for the users
*/
SSH_LOG_PROTOCOL,
- /** Lower level protocol infomations, packet level
+ /** Debug information, to see what is going on
*/
SSH_LOG_PACKET,
- /** Every function path
+ /** Trace information and recoverable error messages
*/
SSH_LOG_FUNCTIONS
};
@@ -351,17 +350,25 @@ enum {
/** No logging at all */
#define SSH_LOG_NONE 0
-/** Show only warnings */
+/** Show only fatal warnings */
#define SSH_LOG_WARN 1
/** Get some information what's going on */
#define SSH_LOG_INFO 2
-/** Get detailed debuging information **/
+/** Get detailed debugging information **/
#define SSH_LOG_DEBUG 3
/** Get trace output, packet information, ... */
#define SSH_LOG_TRACE 4
/** @} */
+enum ssh_control_master_options_e {
+ SSH_CONTROL_MASTER_NO,
+ SSH_CONTROL_MASTER_AUTO,
+ SSH_CONTROL_MASTER_YES,
+ SSH_CONTROL_MASTER_ASK,
+ SSH_CONTROL_MASTER_AUTOASK
+};
+
enum ssh_options_e {
SSH_OPTIONS_HOST,
SSH_OPTIONS_PORT,
@@ -404,6 +411,12 @@ enum ssh_options_e {
SSH_OPTIONS_PROCESS_CONFIG,
SSH_OPTIONS_REKEY_DATA,
SSH_OPTIONS_REKEY_TIME,
+ SSH_OPTIONS_RSA_MIN_SIZE,
+ SSH_OPTIONS_IDENTITY_AGENT,
+ SSH_OPTIONS_IDENTITIES_ONLY,
+ SSH_OPTIONS_CONTROL_MASTER,
+ SSH_OPTIONS_CONTROL_PATH,
+ SSH_OPTIONS_CERTIFICATE,
};
enum {
@@ -466,6 +479,8 @@ LIBSSH_API int ssh_channel_request_exec(ssh_channel channel, const char *cmd);
LIBSSH_API int ssh_channel_request_pty(ssh_channel channel);
LIBSSH_API int ssh_channel_request_pty_size(ssh_channel channel, const char *term,
int cols, int rows);
+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);
LIBSSH_API int ssh_channel_request_shell(ssh_channel channel);
LIBSSH_API int ssh_channel_request_send_signal(ssh_channel channel, const char *signum);
LIBSSH_API int ssh_channel_request_send_break(ssh_channel channel, uint32_t length);
@@ -475,8 +490,6 @@ LIBSSH_API int ssh_channel_request_x11(ssh_channel channel, int single_connectio
const char *cookie, int screen_number);
LIBSSH_API int ssh_channel_request_auth_agent(ssh_channel channel);
LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
-LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
- timeval * timeout);
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
ssh_counter counter);
@@ -507,7 +520,12 @@ LIBSSH_API char *ssh_dirname (const char *path);
LIBSSH_API int ssh_finalize(void);
/* REVERSE PORT FORWARDING */
-LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
+LIBSSH_API ssh_channel ssh_channel_open_forward_port(ssh_session session,
+ int timeout_ms,
+ int *destination_port,
+ char **originator,
+ int *originator_port);
+SSH_DEPRECATED LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
int timeout_ms,
int *destination_port);
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
@@ -526,6 +544,7 @@ LIBSSH_API socket_t ssh_get_fd(ssh_session session);
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
+LIBSSH_API int ssh_request_no_more_sessions(ssh_session session);
LIBSSH_API int ssh_get_server_publickey(ssh_session session, ssh_key *key);
@@ -549,7 +568,27 @@ SSH_DEPRECATED LIBSSH_API int ssh_write_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API char *ssh_dump_knownhost(ssh_session session);
SSH_DEPRECATED LIBSSH_API int ssh_is_server_known(ssh_session session);
SSH_DEPRECATED LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
+SSH_DEPRECATED LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
+ timeval * timeout);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_close(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
+SSH_DEPRECATED LIBSSH_API void ssh_scp_free(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_init(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
+SSH_DEPRECATED LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
+SSH_DEPRECATED LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
@@ -587,6 +626,10 @@ LIBSSH_API int ssh_set_log_level(int level);
LIBSSH_API int ssh_get_log_level(void);
LIBSSH_API void *ssh_get_log_userdata(void);
LIBSSH_API int ssh_set_log_userdata(void *data);
+LIBSSH_API void ssh_vlog(int verbosity,
+ const char *function,
+ const char *format,
+ va_list *va) PRINTF_ATTRIBUTE(3, 0);
LIBSSH_API void _ssh_log(int verbosity,
const char *function,
const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
@@ -645,6 +688,12 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
/** @} */
+enum ssh_file_format_e {
+ SSH_FILE_FORMAT_DEFAULT = 0,
+ SSH_FILE_FORMAT_OPENSSH,
+ SSH_FILE_FORMAT_PEM,
+};
+
LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
@@ -657,6 +706,7 @@ LIBSSH_API int ssh_key_is_private(const ssh_key k);
LIBSSH_API int ssh_key_cmp(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
+LIBSSH_API ssh_key ssh_key_dup(const ssh_key key);
LIBSSH_API int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
ssh_key *pkey);
@@ -670,6 +720,13 @@ LIBSSH_API int ssh_pki_export_privkey_base64(const ssh_key privkey,
ssh_auth_callback auth_fn,
void *auth_data,
char **b64_key);
+LIBSSH_API int
+ssh_pki_export_privkey_base64_format(const ssh_key privkey,
+ const char *passphrase,
+ ssh_auth_callback auth_fn,
+ void *auth_data,
+ char **b64_key,
+ enum ssh_file_format_e format);
LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
const char *passphrase,
ssh_auth_callback auth_fn,
@@ -680,6 +737,13 @@ LIBSSH_API int ssh_pki_export_privkey_file(const ssh_key privkey,
ssh_auth_callback auth_fn,
void *auth_data,
const char *filename);
+LIBSSH_API int
+ssh_pki_export_privkey_file_format(const ssh_key privkey,
+ const char *passphrase,
+ ssh_auth_callback auth_fn,
+ void *auth_data,
+ const char *filename,
+ enum ssh_file_format_e format);
LIBSSH_API int ssh_pki_copy_cert_to_privkey(const ssh_key cert_key,
ssh_key privkey);
@@ -712,24 +776,6 @@ LIBSSH_API void ssh_print_hash(enum ssh_publickey_hash_type type, unsigned char
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
LIBSSH_API void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds);
-LIBSSH_API int ssh_scp_accept_request(ssh_scp scp);
-LIBSSH_API int ssh_scp_close(ssh_scp scp);
-LIBSSH_API int ssh_scp_deny_request(ssh_scp scp, const char *reason);
-LIBSSH_API void ssh_scp_free(ssh_scp scp);
-LIBSSH_API int ssh_scp_init(ssh_scp scp);
-LIBSSH_API int ssh_scp_leave_directory(ssh_scp scp);
-LIBSSH_API ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location);
-LIBSSH_API int ssh_scp_pull_request(ssh_scp scp);
-LIBSSH_API int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode);
-LIBSSH_API int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int perms);
-LIBSSH_API int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int perms);
-LIBSSH_API int ssh_scp_read(ssh_scp scp, void *buffer, size_t size);
-LIBSSH_API const char *ssh_scp_request_get_filename(ssh_scp scp);
-LIBSSH_API int ssh_scp_request_get_permissions(ssh_scp scp);
-LIBSSH_API size_t ssh_scp_request_get_size(ssh_scp scp);
-LIBSSH_API uint64_t ssh_scp_request_get_size64(ssh_scp scp);
-LIBSSH_API const char *ssh_scp_request_get_warning(ssh_scp scp);
-LIBSSH_API int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len);
LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout);
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
@@ -753,10 +799,8 @@ LIBSSH_API int ssh_userauth_try_publickey(ssh_session session,
LIBSSH_API int ssh_userauth_publickey(ssh_session session,
const char *username,
const ssh_key privkey);
-#ifndef _WIN32
LIBSSH_API int ssh_userauth_agent(ssh_session session,
const char *username);
-#endif
LIBSSH_API int ssh_userauth_publickey_auto_get_current_identity(ssh_session session,
char** value);
LIBSSH_API int ssh_userauth_publickey_auto(ssh_session session,
@@ -827,6 +871,7 @@ LIBSSH_API int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t
LIBSSH_API uint32_t ssh_buffer_get_data(ssh_buffer buffer, void *data, uint32_t requestedlen);
LIBSSH_API void *ssh_buffer_get(ssh_buffer buffer);
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
+LIBSSH_API int ssh_session_set_disconnect_message(ssh_session session, const char *message);
#ifndef LIBSSH_LEGACY_0_4
#include "libssh/legacy.h"
diff --git a/include/libssh/libsshpp.hpp b/include/libssh/libsshpp.hpp
index 75c9c7a1..e0f21e85 100644
--- a/include/libssh/libsshpp.hpp
+++ b/include/libssh/libsshpp.hpp
@@ -369,13 +369,11 @@ public:
return state;
}
void log(int priority, const char *format, ...){
- char buffer[1024];
va_list va;
va_start(va, format);
- vsnprintf(buffer, sizeof(buffer), format, va);
+ ssh_vlog(priority, "libsshpp", format, &va);
va_end(va);
- _ssh_log(priority, "libsshpp", "%s", buffer);
}
/** @brief copies options from a session to another
@@ -525,7 +523,7 @@ public:
return ssh_channel_is_open(channel) != 0;
}
int openForward(const char *remotehost, int remoteport,
- const char *sourcehost=NULL, int localport=0){
+ const char *sourcehost, int localport=0){
int err=ssh_channel_open_forward(channel,remotehost,remoteport,
sourcehost, localport);
ssh_throw(err);
@@ -589,9 +587,12 @@ public:
ssh_throw(err);
return_throwable;
}
- void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){
+ void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0,
+ const unsigned char* modes=NULL, size_t modes_len=0){
int err;
- if(term != NULL && cols != 0 && rows != 0)
+ if(term != NULL && cols != 0 && rows != 0 && modes != NULL)
+ err=ssh_channel_request_pty_size_modes(channel,term,cols,rows,modes,modes_len);
+ else if(term != NULL && cols != 0 && rows != 0)
err=ssh_channel_request_pty_size(channel,term,cols,rows);
else
err=ssh_channel_request_pty(channel);
@@ -632,8 +633,8 @@ public:
* @param is_stderr write should be done on the stderr channel (server only)
* @returns number of bytes written
* @throws SshException in case of error
- * @see channel_write
- * @see channel_write_stderr
+ * @see ssh_channel_write
+ * @see ssh_channel_write_stderr
*/
int write(const void *data, size_t len, bool is_stderr=false){
int ret;
@@ -671,7 +672,7 @@ private:
inline Channel *Session::acceptForward(int timeout_ms){
ssh_channel forward =
- ssh_channel_accept_forward(c_session, timeout_ms, NULL);
+ ssh_channel_open_forward_port(c_session, timeout_ms, NULL, NULL, NULL);
ssh_throw_null(c_session,forward);
Channel *newchan = new Channel(*this,forward);
return newchan;
diff --git a/include/libssh/messages.h b/include/libssh/messages.h
index 04d041d4..160306cc 100644
--- a/include/libssh/messages.h
+++ b/include/libssh/messages.h
@@ -28,6 +28,7 @@ struct ssh_auth_request {
int method;
char *password;
struct ssh_key_struct *pubkey;
+ char *sigtype;
enum ssh_publickey_state_e signature_state;
char kbdint_response;
};
@@ -91,6 +92,10 @@ struct ssh_message_struct {
struct ssh_global_request global_request;
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
SSH_PACKET_CALLBACK(ssh_packet_channel_open);
SSH_PACKET_CALLBACK(ssh_packet_global_request);
@@ -103,4 +108,8 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
const char *request, uint8_t want_reply);
ssh_message ssh_message_pop_head(ssh_session session);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* MESSAGES_H_ */
diff --git a/include/libssh/misc.h b/include/libssh/misc.h
index 5044817a..fc8596f7 100644
--- a/include/libssh/misc.h
+++ b/include/libssh/misc.h
@@ -21,6 +21,25 @@
#ifndef MISC_H_
#define MISC_H_
+#ifdef _WIN32
+
+# ifdef _MSC_VER
+# ifndef _SSIZE_T_DEFINED
+# undef ssize_t
+# include <BaseTsd.h>
+ typedef _W64 SSIZE_T ssize_t;
+# define _SSIZE_T_DEFINED
+# endif /* _SSIZE_T_DEFINED */
+# endif /* _MSC_VER */
+
+#else
+# include <sys/types.h>
+#endif /* _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* in misc.c */
/* gets the user home dir. */
char *ssh_get_user_home_dir(void);
@@ -75,13 +94,13 @@ const void *_ssh_list_pop_head(struct ssh_list *list);
/** @brief fetch the head element of a list and remove it from list
* @param type type of the element to return
- * @param list the ssh_list to use
+ * @param ssh_list the ssh_list to use
* @return the first element of the list, or NULL if the list is empty
*/
#define ssh_list_pop_head(type, ssh_list)\
((type)_ssh_list_pop_head(ssh_list))
-int ssh_make_milliseconds(long sec, long usec);
+int ssh_make_milliseconds(unsigned long sec, unsigned long usec);
void ssh_timestamp_init(struct ssh_timestamp *ts);
int ssh_timeout_elapsed(struct ssh_timestamp *ts, int timeout);
int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
@@ -96,7 +115,18 @@ int ssh_mkdirs(const char *pathname, mode_t mode);
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
int ssh_newline_vis(const char *string, char *buf, size_t buf_len);
-int ssh_tmpname(char *template);
+int ssh_tmpname(char *name);
char *ssh_strreplace(const char *src, const char *pattern, const char *repl);
+
+ssize_t ssh_readn(int fd, void *buf, size_t nbytes);
+ssize_t ssh_writen(int fd, const void *buf, size_t nbytes);
+
+int ssh_check_hostname_syntax(const char *hostname);
+int ssh_check_username_syntax(const char *username);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* MISC_H_ */
diff --git a/include/libssh/options.h b/include/libssh/options.h
index e8dc6c69..d32e1589 100644
--- a/include/libssh/options.h
+++ b/include/libssh/options.h
@@ -21,11 +21,22 @@
#ifndef _OPTIONS_H
#define _OPTIONS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ssh_config_parse_file(ssh_session session, const char *filename);
int ssh_config_parse_string(ssh_session session, const char *input);
int ssh_options_set_algo(ssh_session session,
enum ssh_kex_types_e algo,
- const char *list);
+ const char *list,
+ char **place);
int ssh_options_apply(ssh_session session);
+char *ssh_options_get_algo(ssh_session session, enum ssh_kex_types_e algo);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _OPTIONS_H */
diff --git a/include/libssh/packet.h b/include/libssh/packet.h
index 8fc7ce42..f0c8cb20 100644
--- a/include/libssh/packet.h
+++ b/include/libssh/packet.h
@@ -51,6 +51,10 @@ enum ssh_packet_filter_result_e {
int ssh_packet_send(ssh_session session);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
@@ -63,11 +67,12 @@ SSH_PACKET_CALLBACK(ssh_packet_ext_info);
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
#endif
+int ssh_packet_send_newkeys(ssh_session session);
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum);
int ssh_packet_parse_type(ssh_session session);
//int packet_flush(ssh_session session, int enforce_blocking);
-int ssh_packet_socket_callback(const void *data, size_t len, void *user);
+size_t ssh_packet_socket_callback(const void *data, size_t len, void *user);
void ssh_packet_register_socket_callback(ssh_session session, struct ssh_socket_struct *s);
void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
void ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks);
@@ -80,7 +85,7 @@ int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *sourc
size_t start, size_t encrypted_size);
unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet,
- unsigned int len);
+ size_t len);
int ssh_packet_hmac_verify(ssh_session session, const void *data, size_t len,
unsigned char *mac, enum ssh_hmac_e type);
int ssh_packet_set_newkeys(ssh_session session,
@@ -88,4 +93,8 @@ int ssh_packet_set_newkeys(ssh_session session,
struct ssh_crypto_struct *ssh_packet_get_current_crypto(ssh_session session,
enum ssh_crypto_direction_e direction);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* PACKET_H_ */
diff --git a/include/libssh/pcap.h b/include/libssh/pcap.h
index 2e43ae87..2a6c3c27 100644
--- a/include/libssh/pcap.h
+++ b/include/libssh/pcap.h
@@ -27,6 +27,10 @@
#ifdef WITH_PCAP
typedef struct ssh_pcap_context_struct* ssh_pcap_context;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ssh_pcap_file_write_packet(ssh_pcap_file pcap, ssh_buffer packet, uint32_t original_len);
ssh_pcap_context ssh_pcap_context_new(ssh_session session);
@@ -41,5 +45,9 @@ int ssh_pcap_context_write(ssh_pcap_context,enum ssh_pcap_direction direction, v
uint32_t len, uint32_t origlen);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* WITH_PCAP */
#endif /* PCAP_H_ */
diff --git a/include/libssh/pki.h b/include/libssh/pki.h
index 6357b0b6..efb9bdbf 100644
--- a/include/libssh/pki.h
+++ b/include/libssh/pki.h
@@ -33,8 +33,8 @@
#include <openssl/evp.h>
#endif
#include "libssh/crypto.h"
-#ifdef HAVE_OPENSSL_ED25519
-/* If using OpenSSL implementation, define the signature lenght which would be
+#ifdef HAVE_LIBCRYPTO
+/* If using OpenSSL implementation, define the signature length which would be
* defined in libssh/ed25519.h otherwise */
#define ED25519_SIG_LEN 64
#else
@@ -57,32 +57,24 @@ struct ssh_key_struct {
const char *type_c; /* Don't free it ! it is static */
int ecdsa_nid;
#if defined(HAVE_LIBGCRYPT)
- gcry_sexp_t dsa;
gcry_sexp_t rsa;
gcry_sexp_t ecdsa;
#elif defined(HAVE_LIBMBEDCRYPTO)
mbedtls_pk_context *rsa;
mbedtls_ecdsa_context *ecdsa;
- void *dsa;
#elif defined(HAVE_LIBCRYPTO)
- DSA *dsa;
- RSA *rsa;
- EVP_PKEY *key; /* Saving the OpenSSL context here to save time while converting*/
-# if defined(HAVE_OPENSSL_ECC)
- EC_KEY *ecdsa;
-# else
- void *ecdsa;
-# endif /* HAVE_OPENSSL_EC_H */
-#endif /* HAVE_LIBGCRYPT */
-#ifdef HAVE_OPENSSL_ED25519
+ /* This holds either ENGINE key for PKCS#11 support or just key in
+ * high-level format */
+ EVP_PKEY *key;
uint8_t *ed25519_pubkey;
uint8_t *ed25519_privkey;
-#else
+#endif /* HAVE_LIBGCRYPT */
+#ifndef HAVE_LIBCRYPTO
ed25519_pubkey *ed25519_pubkey;
ed25519_privkey *ed25519_privkey;
-#endif
+#endif /* HAVE_LIBCRYPTO */
ssh_string sk_application;
- void *cert;
+ ssh_buffer cert;
enum ssh_keytypes_e cert_type;
};
@@ -91,16 +83,15 @@ struct ssh_signature_struct {
enum ssh_digest_e hash_type;
const char *type_c;
#if defined(HAVE_LIBGCRYPT)
- gcry_sexp_t dsa_sig;
gcry_sexp_t rsa_sig;
gcry_sexp_t ecdsa_sig;
#elif defined(HAVE_LIBMBEDCRYPTO)
ssh_string rsa_sig;
struct mbedtls_ecdsa_sig ecdsa_sig;
#endif /* HAVE_LIBGCRYPT */
-#ifndef HAVE_OPENSSL_ED25519
+#ifndef HAVE_LIBCRYPTO
ed25519_signature *ed25519_sig;
-#endif
+#endif /* HAVE_LIBGCRYPT */
ssh_string raw_sig;
/* Security Key specific additions */
@@ -110,8 +101,11 @@ struct ssh_signature_struct {
typedef struct ssh_signature_struct *ssh_signature;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* SSH Key Functions */
-ssh_key ssh_key_dup(const ssh_key key);
void ssh_key_clean (ssh_key key);
const char *
@@ -127,10 +121,11 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name);
((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521)
#define is_cert_type(kt)\
- ((kt) == SSH_KEYTYPE_DSS_CERT01 ||\
- (kt) == SSH_KEYTYPE_RSA_CERT01 ||\
- ((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
- (kt) <= SSH_KEYTYPE_ED25519_CERT01))
+ ((kt) == SSH_KEYTYPE_RSA_CERT01 ||\
+ (kt) == SSH_KEYTYPE_SK_ECDSA_CERT01 ||\
+ (kt) == SSH_KEYTYPE_SK_ED25519_CERT01 ||\
+ ((kt) >= SSH_KEYTYPE_ECDSA_P256_CERT01 &&\
+ (kt) <= SSH_KEYTYPE_ED25519_CERT01))
/* SSH Signature Functions */
ssh_signature ssh_signature_new(void);
@@ -158,6 +153,10 @@ int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
int ssh_pki_import_cert_blob(const ssh_string cert_blob,
ssh_key *pkey);
+/* SSH Private Key Functions */
+int ssh_pki_export_privkey_blob(const ssh_key key,
+ ssh_string *pblob);
+
/* SSH Signing Functions */
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
@@ -174,9 +173,19 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key);
ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key);
int ssh_key_algorithm_allowed(ssh_session session, const char *type);
+bool ssh_key_size_allowed(ssh_session session, ssh_key key);
+
+/* Return the key size in bits */
+int ssh_key_size(ssh_key key);
/* PKCS11 URI function to check if filename is a path or a PKCS11 URI */
+#ifdef WITH_PKCS11_URI
bool ssh_pki_is_uri(const char *filename);
char *ssh_pki_export_pub_uri_from_priv_uri(const char *priv_uri);
+#endif /* WITH_PKCS11_URI */
+
+#ifdef __cplusplus
+}
+#endif
#endif /* PKI_H_ */
diff --git a/include/libssh/pki_priv.h b/include/libssh/pki_priv.h
index 71418fdc..2061ebd7 100644
--- a/include/libssh/pki_priv.h
+++ b/include/libssh/pki_priv.h
@@ -23,6 +23,10 @@
#include "libssh/pki.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* defined in bcrypt_pbkdf.c */
int bcrypt_pbkdf(const char *pass,
size_t passlen,
@@ -34,8 +38,6 @@ int bcrypt_pbkdf(const char *pass,
#define RSA_HEADER_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
#define RSA_HEADER_END "-----END RSA PRIVATE KEY-----"
-#define DSA_HEADER_BEGIN "-----BEGIN DSA PRIVATE KEY-----"
-#define DSA_HEADER_END "-----END DSA PRIVATE KEY-----"
#define ECDSA_HEADER_BEGIN "-----BEGIN EC PRIVATE KEY-----"
#define ECDSA_HEADER_END "-----END EC PRIVATE KEY-----"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
@@ -49,6 +51,8 @@ enum ssh_key_e {
SSH_KEY_PRIVATE
};
+void pki_key_clean(ssh_key key);
+
int pki_key_ecdsa_nid_from_name(const char *name);
const char *pki_key_ecdsa_nid_to_name(int nid);
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
@@ -59,7 +63,6 @@ enum ssh_digest_e ssh_key_type_to_hash(ssh_session session,
/* SSH Key Functions */
ssh_key pki_key_dup(const ssh_key key, int demote);
int pki_key_generate_rsa(ssh_key key, int parameter);
-int pki_key_generate_dss(ssh_key key, int parameter);
int pki_key_generate_ecdsa(ssh_key key, int parameter);
int pki_key_generate_ed25519(ssh_key key);
@@ -85,24 +88,13 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type,
ssh_key *pkey);
/* SSH Public Key Functions */
-int pki_pubkey_build_dss(ssh_key key,
- ssh_string p,
- ssh_string q,
- ssh_string g,
- ssh_string pubkey);
int pki_pubkey_build_rsa(ssh_key key,
ssh_string e,
ssh_string n);
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e);
-ssh_string pki_publickey_to_blob(const ssh_key key);
+ssh_string pki_key_to_blob(const ssh_key key, enum ssh_key_e type);
/* SSH Private Key Functions */
-int pki_privkey_build_dss(ssh_key key,
- ssh_string p,
- ssh_string q,
- ssh_string g,
- ssh_string pubkey,
- ssh_string privkey);
int pki_privkey_build_rsa(ssh_key key,
ssh_string n,
ssh_string e,
@@ -114,7 +106,6 @@ int pki_privkey_build_ecdsa(ssh_key key,
int nid,
ssh_string e,
ssh_string exp);
-ssh_string pki_publickey_to_blob(const ssh_key key);
/* SSH Signature Functions */
ssh_signature pki_sign_data(const ssh_key privkey,
@@ -140,15 +131,18 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
const unsigned char *hash,
size_t hlen,
enum ssh_digest_e hash_type);
+#ifndef HAVE_LIBCRYPTO
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
const unsigned char *hash, size_t hlen);
+#endif /* HAVE_LIBCRYPTO */
int pki_ed25519_key_cmp(const ssh_key k1,
const ssh_key k2,
enum ssh_keycmp_e what);
-int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
+int pki_ed25519_key_dup(ssh_key new_key, const ssh_key key);
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
+int pki_ed25519_private_key_to_blob(ssh_buffer buffer, const ssh_key privkey);
ssh_string pki_ed25519_signature_to_blob(ssh_signature sig);
int pki_signature_from_ed25519_blob(ssh_signature sig, ssh_string sig_blob);
int pki_privkey_build_ed25519(ssh_key key,
@@ -162,7 +156,14 @@ ssh_key ssh_pki_openssh_privkey_import(const char *text_key,
ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
const char *passphrase, ssh_auth_callback auth_fn, void *auth_data);
+#ifdef WITH_PKCS11_URI
/* URI Function */
int pki_uri_import(const char *uri_name, ssh_key *key, enum ssh_key_e key_type);
+#endif /* WITH_PKCS11_URI */
+
+bool ssh_key_size_allowed_rsa(int min_size, ssh_key key);
+#ifdef __cplusplus
+}
+#endif
#endif /* PKI_PRIV_H_ */
diff --git a/include/libssh/poll.h b/include/libssh/poll.h
index 3aa9a49b..8e30676e 100644
--- a/include/libssh/poll.h
+++ b/include/libssh/poll.h
@@ -114,6 +114,10 @@ typedef unsigned long int nfds_t;
#endif /* WIN32 */
#endif /* HAVE_POLL */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void ssh_poll_init(void);
void ssh_poll_cleanup(void);
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout);
@@ -158,4 +162,8 @@ ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
int ssh_event_add_poll(ssh_event event, ssh_poll_handle p);
void ssh_event_remove_poll(ssh_event event, ssh_poll_handle p);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* POLL_H_ */
diff --git a/include/libssh/poly1305.h b/include/libssh/poly1305.h
index 513f1b99..a22fea87 100644
--- a/include/libssh/poly1305.h
+++ b/include/libssh/poly1305.h
@@ -7,6 +7,10 @@
#define POLY1305_H
#include "libssh/chacha20-poly1305-common.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen,
const uint8_t key[POLY1305_KEYLEN])
#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
@@ -16,4 +20,8 @@ void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen,
#endif
;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* POLY1305_H */
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index b18ece4c..bfef771d 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -29,6 +29,7 @@
#ifndef _LIBSSH_PRIV_H
#define _LIBSSH_PRIV_H
+#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -46,6 +47,14 @@
# endif
#endif /* !defined(HAVE_STRTOULL) */
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if !defined(HAVE_STRNDUP)
char *strndup(const char *s, size_t n);
#endif /* ! HAVE_STRNDUP */
@@ -151,10 +160,26 @@ char *strndup(const char *s, size_t n);
# endif /* _MSC_VER */
struct timeval;
-int gettimeofday(struct timeval *__p, void *__t);
+int ssh_gettimeofday(struct timeval *__p, void *__t);
+
+#define gettimeofday ssh_gettimeofday
#define _XCLOSESOCKET closesocket
+# ifdef HAVE_IO_H
+# include <io.h>
+# undef open
+# define open _open
+# undef close
+# define close _close
+# undef read
+# define read _read
+# undef write
+# define write _write
+# undef unlink
+# define unlink _unlink
+# endif /* HAVE_IO_H */
+
#else /* _WIN32 */
#include <unistd.h>
@@ -167,6 +192,14 @@ int gettimeofday(struct timeval *__p, void *__t);
#include "libssh/callbacks.h"
/* some constants */
+#ifndef PATH_MAX
+#ifdef MAX_PATH
+#define PATH_MAX MAX_PATH
+#else
+#define PATH_MAX 4096
+#endif
+#endif
+
#ifndef MAX_PACKET_LEN
#define MAX_PACKET_LEN 262144
#endif
@@ -275,6 +308,7 @@ int ssh_auth_reply_success(ssh_session session, int partial);
/* client.c */
int ssh_send_banner(ssh_session session, int is_server);
+void ssh_session_socket_close(ssh_session session);
/* connect.c */
socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
@@ -290,7 +324,7 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen);
/* match.c */
int match_pattern_list(const char *string, const char *pattern,
- unsigned int len, int dolower);
+ size_t len, int dolower);
int match_hostname(const char *host, const char *pattern, unsigned int len);
/* connector.c */
@@ -420,4 +454,15 @@ void ssh_agent_state_free(void *data);
bool is_ssh_initialized(void);
+#define SSH_ERRNO_MSG_MAX 1024
+char *ssh_strerror(int err_num, char *buf, size_t buflen);
+
+/** 55 defined options (5 bytes each) + terminator */
+#define SSH_TTY_MODES_MAX_BUFSIZE (55 * 5 + 1)
+int encode_current_tty_opts(unsigned char *buf, size_t buflen);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _LIBSSH_PRIV_H */
diff --git a/include/libssh/sc25519.h b/include/libssh/sc25519.h
index 5a2c1b85..43b09a05 100644
--- a/include/libssh/sc25519.h
+++ b/include/libssh/sc25519.h
@@ -35,6 +35,10 @@ typedef struct {
uint32_t v[16];
} shortsc25519;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
@@ -71,4 +75,8 @@ void sc25519_window5(signed char r[51], const sc25519 *s);
void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/libssh/scp.h b/include/libssh/scp.h
index d356d89b..089fcfc9 100644
--- a/include/libssh/scp.h
+++ b/include/libssh/scp.h
@@ -47,9 +47,17 @@ struct ssh_scp_struct {
int request_mode;
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len);
int ssh_scp_integer_mode(const char *mode);
char *ssh_scp_string_mode(int mode);
int ssh_scp_response(ssh_scp scp, char **response);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/include/libssh/server.h b/include/libssh/server.h
index 41f89d5c..e437f292 100644
--- a/include/libssh/server.h
+++ b/include/libssh/server.h
@@ -36,26 +36,29 @@ extern "C" {
#endif
enum ssh_bind_options_e {
- SSH_BIND_OPTIONS_BINDADDR,
- SSH_BIND_OPTIONS_BINDPORT,
- SSH_BIND_OPTIONS_BINDPORT_STR,
- SSH_BIND_OPTIONS_HOSTKEY,
- SSH_BIND_OPTIONS_DSAKEY,
- SSH_BIND_OPTIONS_RSAKEY,
- SSH_BIND_OPTIONS_BANNER,
- SSH_BIND_OPTIONS_LOG_VERBOSITY,
- SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
- SSH_BIND_OPTIONS_ECDSAKEY,
- SSH_BIND_OPTIONS_IMPORT_KEY,
- SSH_BIND_OPTIONS_KEY_EXCHANGE,
- SSH_BIND_OPTIONS_CIPHERS_C_S,
- SSH_BIND_OPTIONS_CIPHERS_S_C,
- SSH_BIND_OPTIONS_HMAC_C_S,
- SSH_BIND_OPTIONS_HMAC_S_C,
- SSH_BIND_OPTIONS_CONFIG_DIR,
- SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
- SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
- SSH_BIND_OPTIONS_PROCESS_CONFIG,
+ SSH_BIND_OPTIONS_BINDADDR,
+ SSH_BIND_OPTIONS_BINDPORT,
+ SSH_BIND_OPTIONS_BINDPORT_STR,
+ SSH_BIND_OPTIONS_HOSTKEY,
+ SSH_BIND_OPTIONS_DSAKEY, /* deprecated */
+ SSH_BIND_OPTIONS_RSAKEY, /* deprecated */
+ SSH_BIND_OPTIONS_BANNER,
+ SSH_BIND_OPTIONS_LOG_VERBOSITY,
+ SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
+ SSH_BIND_OPTIONS_ECDSAKEY, /* deprecated */
+ SSH_BIND_OPTIONS_IMPORT_KEY,
+ SSH_BIND_OPTIONS_KEY_EXCHANGE,
+ SSH_BIND_OPTIONS_CIPHERS_C_S,
+ SSH_BIND_OPTIONS_CIPHERS_S_C,
+ SSH_BIND_OPTIONS_HMAC_C_S,
+ SSH_BIND_OPTIONS_HMAC_S_C,
+ SSH_BIND_OPTIONS_CONFIG_DIR,
+ SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES,
+ SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS,
+ SSH_BIND_OPTIONS_PROCESS_CONFIG,
+ SSH_BIND_OPTIONS_MODULI,
+ SSH_BIND_OPTIONS_RSA_MIN_SIZE,
+ SSH_BIND_OPTIONS_IMPORT_KEY_STR,
};
typedef struct ssh_bind_struct* ssh_bind;
@@ -115,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 occured.
+ * @return SSH_OK on success, SSH_ERROR if an error occurred.
*
* @code
* struct ssh_callbacks_struct cb = {
@@ -220,6 +223,9 @@ LIBSSH_API int ssh_server_init_kex(ssh_session session);
/**
* @brief Free a ssh servers bind.
*
+ * Note that this will also free options that have been set on the bind,
+ * including keys set with SSH_BIND_OPTIONS_IMPORT_KEY.
+ *
* @param ssh_bind_o The ssh server bind to free.
*/
LIBSSH_API void ssh_bind_free(ssh_bind ssh_bind_o);
@@ -243,6 +249,18 @@ LIBSSH_API void ssh_bind_free(ssh_bind ssh_bind_o);
*/
LIBSSH_API void ssh_set_auth_methods(ssh_session session, int auth_methods);
+/**
+ * @brief Send the server's issue-banner to client.
+ *
+ *
+ * @param[in] session The server session.
+ *
+ * @param[in] banner The server's banner.
+ *
+ * @return SSH_OK on success, SSH_ERROR on error.
+ */
+LIBSSH_API int ssh_send_issue_banner(ssh_session session, const ssh_string banner);
+
/**********************************************************
* SERVER MESSAGING
**********************************************************/
@@ -266,7 +284,7 @@ LIBSSH_API int ssh_message_reply_default(ssh_message msg);
*
* @param[in] msg The message to get the username from.
*
- * @return The username or NULL if an error occured.
+ * @return The username or NULL if an error occurred.
*
* @see ssh_message_get()
* @see ssh_message_type()
@@ -278,12 +296,14 @@ LIBSSH_API const char *ssh_message_auth_user(ssh_message msg);
*
* @param[in] msg The message to get the password from.
*
- * @return The username or NULL if an error occured.
+ * @return The password or NULL if an error occurred.
*
* @see ssh_message_get()
* @see ssh_message_type()
+ * @deprecated This function should not be used anymore as there is a
+ * callback based server implementation now auth_password_function.
*/
-LIBSSH_API const char *ssh_message_auth_password(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API const char *ssh_message_auth_password(ssh_message msg);
/**
* @brief Get the publickey of the authenticated user.
@@ -298,11 +318,21 @@ LIBSSH_API const char *ssh_message_auth_password(ssh_message msg);
* @see ssh_key_cmp()
* @see ssh_message_get()
* @see ssh_message_type()
+ * @deprecated This function should not be used anymore as there is a
+ * callback based server implementation auth_pubkey_function.
*/
-LIBSSH_API ssh_key ssh_message_auth_pubkey(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API ssh_key ssh_message_auth_pubkey(ssh_message msg);
LIBSSH_API int ssh_message_auth_kbdint_is_response(ssh_message msg);
-LIBSSH_API enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg);
+
+/**
+ * @param[in] msg The message to get the public key state from.
+ *
+ * @deprecated This function should not be used anymore as there is a
+ * callback based server implementation auth_pubkey_function
+ */
+SSH_DEPRECATED LIBSSH_API enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg);
+
LIBSSH_API int ssh_message_auth_reply_success(ssh_message msg,int partial);
LIBSSH_API int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pubkey);
LIBSSH_API int ssh_message_auth_reply_pk_ok_simple(ssh_message msg);
@@ -331,11 +361,12 @@ LIBSSH_API int ssh_message_channel_request_open_destination_port(ssh_message msg
LIBSSH_API ssh_channel ssh_message_channel_request_channel(ssh_message msg);
-LIBSSH_API const char *ssh_message_channel_request_pty_term(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_pty_width(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_pty_height(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_pty_pxwidth(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_pty_pxheight(ssh_message msg);
+/* Replaced by callback based server implementation function channel_pty_request_function*/
+SSH_DEPRECATED LIBSSH_API const char *ssh_message_channel_request_pty_term(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_pty_width(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_pty_height(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_pty_pxwidth(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_pty_pxheight(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_env_name(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_env_value(ssh_message msg);
@@ -344,17 +375,18 @@ LIBSSH_API const char *ssh_message_channel_request_command(ssh_message msg);
LIBSSH_API const char *ssh_message_channel_request_subsystem(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_x11_single_connection(ssh_message msg);
-LIBSSH_API const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg);
-LIBSSH_API const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg);
-LIBSSH_API int ssh_message_channel_request_x11_screen_number(ssh_message msg);
+/* Replaced by callback based server implementation function channel_open_request_x11_function*/
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_x11_single_connection(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API const char *ssh_message_channel_request_x11_auth_protocol(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API const char *ssh_message_channel_request_x11_auth_cookie(ssh_message msg);
+SSH_DEPRECATED LIBSSH_API int ssh_message_channel_request_x11_screen_number(ssh_message msg);
LIBSSH_API const char *ssh_message_global_request_address(ssh_message msg);
LIBSSH_API int ssh_message_global_request_port(ssh_message msg);
LIBSSH_API int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
int remoteport, const char *sourcehost, int localport);
-LIBSSH_API int ssh_channel_open_x11(ssh_channel channel,
+LIBSSH_API int ssh_channel_open_x11(ssh_channel channel,
const char *orig_addr, int orig_port);
LIBSSH_API int ssh_channel_request_send_exit_status(ssh_channel channel,
diff --git a/include/libssh/session.h b/include/libssh/session.h
index 22256150..27da7a83 100644
--- a/include/libssh/session.h
+++ b/include/libssh/session.h
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include "libssh/priv.h"
+#include "libssh/callbacks.h"
#include "libssh/kex.h"
#include "libssh/packet.h"
#include "libssh/pcap.h"
@@ -70,10 +71,24 @@ enum ssh_pending_call_e {
};
/* libssh calls may block an undefined amount of time */
-#define SSH_SESSION_FLAG_BLOCKING 1
+#define SSH_SESSION_FLAG_BLOCKING 0x0001
/* Client successfully authenticated */
-#define SSH_SESSION_FLAG_AUTHENTICATED 2
+#define SSH_SESSION_FLAG_AUTHENTICATED 0x0002
+
+/* Do not accept new session channels (no-more-sessions@openssh.com) */
+#define SSH_SESSION_FLAG_NO_MORE_SESSIONS 0x0004
+
+/* The KEXINIT message can be sent first by either of the parties so this flag
+ * indicates that the message was already sent to make sure it is sent and avoid
+ * sending it twice during key exchange to simplify the state machine. */
+#define SSH_SESSION_FLAG_KEXINIT_SENT 0x0008
+
+/* The current SSH2 session implements the "strict KEX" feature and should behave
+ * differently on SSH2_MSG_NEWKEYS. */
+#define SSH_SESSION_FLAG_KEX_STRICT 0x0010
+/* Unexpected packets have been sent while the session was still unencrypted */
+#define SSH_SESSION_FLAG_KEX_TAINTED 0x0020
/* codes to use with ssh_handle_packets*() */
/* Infinite timeout */
@@ -92,6 +107,13 @@ enum ssh_pending_call_e {
#define SSH_OPT_FLAG_KBDINT_AUTH 0x4
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
+/* Escape expansion of different variables */
+#define SSH_OPT_EXP_FLAG_KNOWNHOSTS 0x1
+#define SSH_OPT_EXP_FLAG_GLOBAL_KNOWNHOSTS 0x2
+#define SSH_OPT_EXP_FLAG_PROXYCOMMAND 0x4
+#define SSH_OPT_EXP_FLAG_IDENTITY 0x8
+#define SSH_OPT_EXP_FLAG_CONTROL_PATH 0x10
+
/* extensions flags */
/* negotiation enabled */
#define SSH_EXT_NEGOTIATION 0x01
@@ -131,10 +153,9 @@ struct ssh_session_struct {
/* Extensions negotiated using RFC 8308 */
uint32_t extensions;
- ssh_string banner; /* that's the issue banner from
- the server */
- char *discon_msg; /* disconnect message from
- the remote host */
+ ssh_string banner; /* that's the issue banner from the server */
+ char *peer_discon_msg; /* disconnect message from the remote host */
+ char *disconnect_message; /* disconnect message to be set */
ssh_buffer in_buffer;
PACKET in_packet;
ssh_buffer out_buffer;
@@ -158,32 +179,39 @@ struct ssh_session_struct {
uint32_t current_method;
} auth;
+ /* Sending this flag before key exchange to save one round trip during the
+ * key exchange. This might make sense on high-latency connections.
+ * So far internal only for testing. Usable only on the client side --
+ * there is no key exchange method that would start with server message */
+ bool send_first_kex_follows;
/*
* RFC 4253, 7.1: if the first_kex_packet_follows flag was set in
* the received SSH_MSG_KEXINIT, but the guess was wrong, this
* field will be set such that the following guessed packet will
- * be ignored. Once that packet has been received and ignored,
- * this field is cleared.
+ * be ignored on the receiving side. Once that packet has been received and
+ * ignored, this field is cleared.
+ * On the sending side, this is set after we got peer KEXINIT message and we
+ * need to resend the initial message of the negotiated KEX algorithm.
*/
- int first_kex_follows_guess_wrong;
+ bool first_kex_follows_guess_wrong;
ssh_buffer in_hashbuf;
ssh_buffer out_hashbuf;
struct ssh_crypto_struct *current_crypto;
- struct ssh_crypto_struct *next_crypto; /* next_crypto is going to be used after a SSH2_MSG_NEWKEYS */
+ /* next_crypto is going to be used after a SSH2_MSG_NEWKEYS */
+ struct ssh_crypto_struct *next_crypto;
struct ssh_list *channels; /* linked list of channels */
- int maxchannel;
+ uint32_t maxchannel;
ssh_agent agent; /* ssh agent */
-/* keyb interactive data */
+ /* keyboard interactive data */
struct ssh_kbdint_struct *kbdint;
struct ssh_gssapi_struct *gssapi;
/* server host keys */
struct {
ssh_key rsa_key;
- ssh_key dsa_key;
ssh_key ecdsa_key;
ssh_key ed25519_key;
/* The type of host key wanted by client */
@@ -193,7 +221,8 @@ struct ssh_session_struct {
/* auths accepted by server */
struct ssh_list *ssh_message_list; /* list of delayed SSH messages */
- int (*ssh_message_callback)( struct ssh_session_struct *session, ssh_message msg, void *userdata);
+ int (*ssh_message_callback)(struct ssh_session_struct *session,
+ ssh_message msg, void *userdata);
void *ssh_message_callback_data;
ssh_server_callbacks server_callbacks;
void (*ssh_connection_callback)( struct ssh_session_struct *session);
@@ -207,6 +236,9 @@ struct ssh_session_struct {
#endif
struct {
struct ssh_list *identity;
+ struct ssh_list *identity_non_exp;
+ struct ssh_list *certificate;
+ struct ssh_list *certificate_non_exp;
char *username;
char *host;
char *bindaddr; /* bind the client to an ip addr */
@@ -217,9 +249,11 @@ struct ssh_session_struct {
char *pubkey_accepted_types;
char *ProxyCommand;
char *custombanner;
+ char *moduli_file;
+ char *agent_socket;
unsigned long timeout; /* seconds */
unsigned long timeout_usec;
- unsigned int port;
+ uint16_t port;
socket_t fd;
int StrictHostKeyChecking;
char compressionlevel;
@@ -227,11 +261,16 @@ struct ssh_session_struct {
char *gss_client_identity;
int gss_delegate_creds;
int flags;
+ int exp_flags;
int nodelay;
bool config_processed;
uint8_t options_seen[SOC_MAX];
uint64_t rekey_data;
uint32_t rekey_time;
+ int rsa_min_size;
+ bool identities_only;
+ int control_master;
+ char *control_path;
} opts;
/* counters */
ssh_counter socket_counter;
@@ -246,7 +285,7 @@ struct ssh_session_struct {
typedef int (*ssh_termination_function)(void *user);
int ssh_handle_packets(ssh_session session, int timeout);
int ssh_handle_packets_termination(ssh_session session,
- long timeout,
+ int timeout,
ssh_termination_function fct,
void *user);
void ssh_socket_exception_callback(int code, int errno_code, void *user);
diff --git a/include/libssh/sftp.h b/include/libssh/sftp.h
index c855df8a..754a54c3 100644
--- a/include/libssh/sftp.h
+++ b/include/libssh/sftp.h
@@ -77,6 +77,8 @@ typedef struct sftp_request_queue_struct* sftp_request_queue;
typedef struct sftp_session_struct* sftp_session;
typedef struct sftp_status_message_struct* sftp_status_message;
typedef struct sftp_statvfs_struct* sftp_statvfs_t;
+typedef struct sftp_limits_struct* sftp_limits_t;
+typedef struct sftp_aio_struct* sftp_aio;
struct sftp_session_struct {
ssh_session session;
@@ -90,6 +92,7 @@ struct sftp_session_struct {
void **handles;
sftp_ext ext;
sftp_packet read_packet;
+ sftp_limits_t limits;
};
struct sftp_packet_struct {
@@ -201,6 +204,16 @@ struct sftp_statvfs_struct {
};
/**
+ * @brief SFTP limits structure.
+ */
+struct sftp_limits_struct {
+ uint64_t max_packet_length; /** maximum number of bytes in a single sftp packet */
+ uint64_t max_read_length; /** maximum length in a SSH_FXP_READ packet */
+ uint64_t max_write_length; /** maximum length in a SSH_FXP_WRITE packet */
+ uint64_t max_open_handles; /** maximum number of active handles allowed by server */
+};
+
+/**
* @brief Creates a new sftp session.
*
* This function creates a new sftp session and allocates a new sftp channel
@@ -476,13 +489,18 @@ LIBSSH_API void sftp_file_set_blocking(sftp_file handle);
/**
* @brief Read from a file using an opened sftp file handle.
*
+ * This function caps the length a user is allowed to read from an sftp file.
+ *
+ * The value used for the cap is same as the value of the max_read_length
+ * field of the sftp_limits_t returned by sftp_limits().
+ *
* @param file The opened sftp file handle to be read from.
*
* @param buf Pointer to buffer to receive read data.
*
* @param count Size of the buffer in bytes.
*
- * @return Number of bytes written, < 0 on error with ssh and sftp
+ * @return Number of bytes read, < 0 on error with ssh and sftp
* error set.
*
* @see sftp_get_error()
@@ -520,7 +538,8 @@ LIBSSH_API ssize_t sftp_read(sftp_file file, void *buf, size_t count);
* @see sftp_async_read()
* @see sftp_open()
*/
-LIBSSH_API int sftp_async_read_begin(sftp_file file, uint32_t len);
+SSH_DEPRECATED LIBSSH_API int sftp_async_read_begin(sftp_file file,
+ uint32_t len);
/**
* @brief Wait for an asynchronous read to complete and save the data.
@@ -545,11 +564,19 @@ LIBSSH_API int sftp_async_read_begin(sftp_file file, uint32_t len);
*
* @see sftp_async_read_begin()
*/
-LIBSSH_API int sftp_async_read(sftp_file file, void *data, uint32_t len, uint32_t id);
+SSH_DEPRECATED LIBSSH_API int sftp_async_read(sftp_file file,
+ void *data,
+ uint32_t len,
+ uint32_t id);
/**
* @brief Write to a file using an opened sftp file handle.
*
+ * This function caps the length a user is allowed to write to an sftp file.
+ *
+ * The value used for the cap is same as the value of the max_write_length
+ * field of the sftp_limits_t returned by sftp_limits().
+ *
* @param file Open sftp file handle to write to.
*
* @param buf Pointer to buffer to write data.
@@ -566,6 +593,229 @@ LIBSSH_API int sftp_async_read(sftp_file file, void *data, uint32_t len, uint32_
LIBSSH_API ssize_t sftp_write(sftp_file file, const void *buf, size_t count);
/**
+ * @brief Deallocate memory corresponding to a sftp aio handle.
+ *
+ * This function deallocates memory corresponding to the aio handle returned
+ * by the sftp_aio_begin_*() functions. Users can use this function to free
+ * memory corresponding to an aio handle for an outstanding async i/o request
+ * on encountering some error.
+ *
+ * @param aio sftp aio handle corresponding to which memory has
+ * to be deallocated.
+ *
+ * @see sftp_aio_begin_read()
+ * @see sftp_aio_wait_read()
+ * @see sftp_aio_begin_write()
+ * @see sftp_aio_wait_write()
+ */
+LIBSSH_API void sftp_aio_free(sftp_aio aio);
+#define SFTP_AIO_FREE(x) \
+ do { if(x != NULL) {sftp_aio_free(x); x = NULL;} } while(0)
+
+/**
+ * @brief Start an asynchronous read from a file using an opened sftp
+ * file handle.
+ *
+ * Its goal is to avoid the slowdowns related to the request/response pattern
+ * of a synchronous read. To do so, you must call 2 functions :
+ *
+ * sftp_aio_begin_read() and sftp_aio_wait_read().
+ *
+ * - The first step is to call sftp_aio_begin_read(). This function sends a
+ * read request to the sftp server, dynamically allocates memory to store
+ * information about the sent request and provides the caller an sftp aio
+ * handle to that memory.
+ *
+ * - The second step is to call sftp_aio_wait_read() and pass it the address
+ * of a location storing the sftp aio handle provided by
+ * sftp_aio_begin_read().
+ *
+ * These two functions do not close the open sftp file handle passed to
+ * sftp_aio_begin_read() irrespective of whether they fail or not.
+ *
+ * It is the responsibility of the caller to ensure that the open sftp file
+ * handle passed to sftp_aio_begin_read() must not be closed before the
+ * corresponding call to sftp_aio_wait_read(). After sftp_aio_wait_read()
+ * returns, it is caller's decision whether to immediately close the file by
+ * calling sftp_close() or to keep it open and perform some more operations
+ * on it.
+ *
+ * This function caps the length a user is allowed to read from an sftp file,
+ * the value of len parameter after capping is returned on success.
+ *
+ * The value used for the cap is same as the value of the max_read_length
+ * field of the sftp_limits_t returned by sftp_limits().
+ *
+ * @param file The opened sftp file handle to be read from.
+ *
+ * @param len Number of bytes to read.
+ *
+ * @param aio Pointer to a location where the sftp aio handle
+ * (corresponding to the sent request) should be stored.
+ *
+ * @returns On success, the number of bytes the server is
+ * requested to read (value of len parameter after
+ * capping). On error, SSH_ERROR with sftp and ssh
+ * errors set.
+ *
+ * @warning When calling this function, the internal file offset is
+ * updated corresponding to the number of bytes requested
+ * to read.
+ *
+ * @warning A call to sftp_aio_begin_read() sends a request to
+ * the server. When the server answers, libssh allocates
+ * memory to store it until sftp_aio_wait_read() is called.
+ * Not calling sftp_aio_wait_read() will lead to memory
+ * leaks.
+ *
+ * @see sftp_aio_wait_read()
+ * @see sftp_aio_free()
+ * @see sftp_open()
+ * @see sftp_close()
+ * @see sftp_get_error()
+ * @see ssh_get_error()
+ */
+LIBSSH_API ssize_t sftp_aio_begin_read(sftp_file file,
+ size_t len,
+ sftp_aio *aio);
+
+/**
+ * @brief Wait for an asynchronous read to complete and store the read data
+ * in the supplied buffer.
+ *
+ * A pointer to an sftp aio handle should be passed while calling
+ * this function. Except when the return value is SSH_AGAIN,
+ * this function releases the memory corresponding to the supplied
+ * aio handle and assigns NULL to that aio handle using the passed
+ * pointer to that handle.
+ *
+ * If the file is opened in non-blocking mode and the request hasn't been
+ * executed yet, this function returns SSH_AGAIN and must be called again
+ * using the same sftp aio handle.
+ *
+ * @param aio Pointer to the sftp aio handle returned by
+ * sftp_aio_begin_read().
+ *
+ * @param buf Pointer to the buffer in which read data will be stored.
+ *
+ * @param buf_size Size of the buffer in bytes. It should be bigger or
+ * equal to the length parameter of the
+ * sftp_aio_begin_read() call.
+ *
+ * @return Number of bytes read, 0 on EOF, SSH_ERROR if an error
+ * occurred, SSH_AGAIN if the file is opened in nonblocking
+ * mode and the request hasn't been executed yet.
+ *
+ * @warning A call to this function with an invalid sftp aio handle
+ * may never return.
+ *
+ * @see sftp_aio_begin_read()
+ * @see sftp_aio_free()
+ */
+LIBSSH_API ssize_t sftp_aio_wait_read(sftp_aio *aio,
+ void *buf,
+ size_t buf_size);
+
+/**
+ * @brief Start an asynchronous write to a file using an opened sftp
+ * file handle.
+ *
+ * Its goal is to avoid the slowdowns related to the request/response pattern
+ * of a synchronous write. To do so, you must call 2 functions :
+ *
+ * sftp_aio_begin_write() and sftp_aio_wait_write().
+ *
+ * - The first step is to call sftp_aio_begin_write(). This function sends a
+ * write request to the sftp server, dynamically allocates memory to store
+ * information about the sent request and provides the caller an sftp aio
+ * handle to that memory.
+ *
+ * - The second step is to call sftp_aio_wait_write() and pass it the address
+ * of a location storing the sftp aio handle provided by
+ * sftp_aio_begin_write().
+ *
+ * These two functions do not close the open sftp file handle passed to
+ * sftp_aio_begin_write() irrespective of whether they fail or not.
+ *
+ * It is the responsibility of the caller to ensure that the open sftp file
+ * handle passed to sftp_aio_begin_write() must not be closed before the
+ * corresponding call to sftp_aio_wait_write(). After sftp_aio_wait_write()
+ * returns, it is caller's decision whether to immediately close the file by
+ * calling sftp_close() or to keep it open and perform some more operations
+ * on it.
+ *
+ * This function caps the length a user is allowed to write to an sftp file,
+ * the value of len parameter after capping is returned on success.
+ *
+ * The value used for the cap is same as the value of the max_write_length
+ * field of the sftp_limits_t returned by sftp_limits().
+ *
+ * @param file The opened sftp file handle to write to.
+ *
+ * @param buf Pointer to the buffer containing data to write.
+ *
+ * @param len Number of bytes to write.
+ *
+ * @param aio Pointer to a location where the sftp aio handle
+ * (corresponding to the sent request) should be stored.
+ *
+ * @returns On success, the number of bytes the server is
+ * requested to write (value of len parameter after
+ * capping). On error, SSH_ERROR with sftp and ssh errors
+ * set.
+ *
+ * @warning When calling this function, the internal file offset is
+ * updated corresponding to the number of bytes requested
+ * to write.
+ *
+ * @warning A call to sftp_aio_begin_write() sends a request to
+ * the server. When the server answers, libssh allocates
+ * memory to store it until sftp_aio_wait_write() is
+ * called. Not calling sftp_aio_wait_write() will lead to
+ * memory leaks.
+ *
+ * @see sftp_aio_wait_write()
+ * @see sftp_aio_free()
+ * @see sftp_open()
+ * @see sftp_close()
+ * @see sftp_get_error()
+ * @see ssh_get_error()
+ */
+LIBSSH_API ssize_t sftp_aio_begin_write(sftp_file file,
+ const void *buf,
+ size_t len,
+ sftp_aio *aio);
+
+/**
+ * @brief Wait for an asynchronous write to complete.
+ *
+ * A pointer to an sftp aio handle should be passed while calling
+ * this function. Except when the return value is SSH_AGAIN,
+ * this function releases the memory corresponding to the supplied
+ * aio handle and assigns NULL to that aio handle using the passed
+ * pointer to that handle.
+ *
+ * If the file is opened in non-blocking mode and the request hasn't
+ * been executed yet, this function returns SSH_AGAIN and must be called
+ * again using the same sftp aio handle.
+ *
+ * @param aio Pointer to the sftp aio handle returned by
+ * sftp_aio_begin_write().
+ *
+ * @return Number of bytes written on success, SSH_ERROR
+ * if an error occurred, SSH_AGAIN if the file is
+ * opened in nonblocking mode and the request hasn't
+ * been executed yet.
+ *
+ * @warning A call to this function with an invalid sftp aio handle
+ * may never return.
+ *
+ * @see sftp_aio_begin_write()
+ * @see sftp_aio_free()
+ */
+LIBSSH_API ssize_t sftp_aio_wait_write(sftp_aio *aio);
+
+/**
* @brief Seek to a specific location in a file.
*
* @param file Open sftp file handle to seek in.
@@ -605,8 +855,7 @@ LIBSSH_API unsigned long sftp_tell(sftp_file file);
* @param file Open sftp file handle.
*
* @return The offset of the current byte relative to the beginning
- * of the file associated with the file descriptor. < 0 on
- * error.
+ * of the file associated with the file descriptor.
*/
LIBSSH_API uint64_t sftp_tell64(sftp_file file);
@@ -681,6 +930,11 @@ LIBSSH_API int sftp_rename(sftp_session sftp, const char *original, const char
/**
* @brief Set file attributes on a file, directory or symbolic link.
*
+ * Note, that this function can only set time values using 32 bit values due to
+ * the restrictions in the SFTP protocol version 3 implemented by libssh.
+ * The support for 64 bit time values was introduced in SFTP version 5, which is
+ * not implemented by libssh nor any major SFTP servers.
+ *
* @param sftp The sftp session handle.
*
* @param file The file which attributes should be changed.
@@ -767,12 +1021,30 @@ LIBSSH_API int sftp_symlink(sftp_session sftp, const char *target, const char *d
* @param path Specifies the path name of the symlink to be read.
*
* @return The target of the link, NULL on error.
+ * The caller needs to free the memory
+ * using ssh_string_free_char().
*
* @see sftp_get_error()
*/
LIBSSH_API char *sftp_readlink(sftp_session sftp, const char *path);
/**
+ * @brief Create a hard link.
+ *
+ * @param sftp The sftp session handle.
+ *
+ * @param oldpath Specifies the pathname of the file for
+ * which the new hardlink is to be created.
+ *
+ * @param newpath Specifies the pathname of the hardlink to be created.
+ *
+ * @return 0 on success, -1 on error with ssh and sftp error set.
+ *
+ * @see sftp_get_error()
+ */
+LIBSSH_API int sftp_hardlink(sftp_session sftp, const char *oldpath, const char *newpath);
+
+/**
* @brief Get information about a mounted file system.
*
* @param sftp The sftp session handle.
@@ -820,6 +1092,24 @@ LIBSSH_API void sftp_statvfs_free(sftp_statvfs_t statvfs_o);
LIBSSH_API int sftp_fsync(sftp_file file);
/**
+ * @brief Get information about the various limits the server might impose.
+ *
+ * @param sftp The sftp session handle.
+ *
+ * @return A limits structure or NULL on error.
+ *
+ * @see sftp_get_error()
+ */
+LIBSSH_API sftp_limits_t sftp_limits(sftp_session sftp);
+
+/**
+ * @brief Free the memory of an allocated limits.
+ *
+ * @param limits The limits to free.
+ */
+LIBSSH_API void sftp_limits_free(sftp_limits_t limits);
+
+/**
* @brief Canonicalize a sftp path.
*
* @param sftp The sftp session handle.
@@ -841,6 +1131,19 @@ LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path);
*/
LIBSSH_API int sftp_server_version(sftp_session sftp);
+/**
+ * @brief Canonicalize path using expand-path@openssh.com extension
+ *
+ * @param sftp The sftp session handle.
+ *
+ * @param path The path to be canonicalized.
+ *
+ * @return A pointer to the newly allocated canonicalized path,
+ * NULL on error. The caller needs to free the memory
+ * using ssh_string_free_char().
+ */
+LIBSSH_API char *sftp_expand_path(sftp_session sftp, const char *path);
+
#ifdef WITH_SERVER
/**
* @brief Create a new sftp server session.
@@ -860,7 +1163,7 @@ LIBSSH_API sftp_session sftp_server_new(ssh_session session, ssh_channel chan);
*
* @return 0 on success, < 0 on error.
*/
-LIBSSH_API int sftp_server_init(sftp_session sftp);
+SSH_DEPRECATED LIBSSH_API int sftp_server_init(sftp_session sftp);
/**
* @brief Close and deallocate a sftp server session.
diff --git a/include/libssh/sftp_priv.h b/include/libssh/sftp_priv.h
index 83925191..8470a8ad 100644
--- a/include/libssh/sftp_priv.h
+++ b/include/libssh/sftp_priv.h
@@ -21,12 +21,63 @@
#ifndef SFTP_PRIV_H
#define SFTP_PRIV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
sftp_packet sftp_packet_read(sftp_session sftp);
-ssize_t sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload);
+int sftp_packet_write(sftp_session sftp, uint8_t type, ssh_buffer payload);
void sftp_packet_free(sftp_packet packet);
int buffer_add_attributes(ssh_buffer buffer, sftp_attributes attr);
sftp_attributes sftp_parse_attr(sftp_session session,
ssh_buffer buf,
int expectname);
+/**
+ * @brief Reply to the SSH_FXP_INIT message with the SSH_FXP_VERSION message
+ *
+ * @param client_msg The pointer to client message.
+ *
+ * @return 0 on success, < 0 on error with ssh and sftp error set.
+ *
+ * @see sftp_get_error()
+ */
+int sftp_reply_version(sftp_client_message client_msg);
+/**
+ * @brief Decode the data from channel buffer into sftp read_packet.
+ *
+ * @param sftp The sftp session handle.
+ *
+ * @param data The pointer to the data buffer of channel.
+ * @param len The data buffer length
+ *
+ * @return Length of data decoded.
+ */
+int sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len);
+
+void sftp_set_error(sftp_session sftp, int errnum);
+
+void sftp_message_free(sftp_message msg);
+
+int sftp_read_and_dispatch(sftp_session sftp);
+
+sftp_message sftp_dequeue(sftp_session sftp, uint32_t id);
+
+/*
+ * Assigns a new SFTP ID for new requests and assures there is no collision
+ * between them.
+ * Returns a new ID ready to use in a request
+ */
+static inline uint32_t sftp_get_new_id(sftp_session session)
+{
+ return ++session->id_counter;
+}
+
+sftp_status_message parse_status_msg(sftp_message msg);
+
+void status_msg_free(sftp_status_message status);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* SFTP_PRIV_H */
diff --git a/include/libssh/sftpserver.h b/include/libssh/sftpserver.h
new file mode 100644
index 00000000..d7ed6e49
--- /dev/null
+++ b/include/libssh/sftpserver.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2022 Zeyu Sheng <shengzeyu19_98@163.com>
+ * Copyright (c) 2023 Red Hat, Inc.
+ *
+ * Authors: Jakub Jelen <jjelen@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SFTP_SERVER_H
+#define SFTP_SERVER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+/**
+ * @defgroup libssh_sftp_server The libssh SFTP server API
+ *
+ * @brief SFTP server handling functions
+ *
+ * TODO
+ *
+ * @{
+ */
+
+#define SSH_SFTP_CALLBACK(name) \
+ static int name(sftp_client_message message)
+
+typedef int (*sftp_server_message_callback)(sftp_client_message message);
+
+struct sftp_message_handler
+{
+ const char *name;
+ const char *extended_name;
+ uint8_t type;
+
+ sftp_server_message_callback cb;
+};
+
+LIBSSH_API int sftp_channel_default_subsystem_request(ssh_session session,
+ ssh_channel channel,
+ const char *subsystem,
+ void *userdata);
+LIBSSH_API int sftp_channel_default_data_callback(ssh_session session,
+ ssh_channel channel,
+ void *data,
+ uint32_t len,
+ int is_stderr,
+ void *userdata);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SFTP_SERVER_H */
diff --git a/include/libssh/socket.h b/include/libssh/socket.h
index 5e345c68..cdd3c837 100644
--- a/include/libssh/socket.h
+++ b/include/libssh/socket.h
@@ -35,13 +35,14 @@ void ssh_socket_reset(ssh_socket s);
void ssh_socket_free(ssh_socket s);
void ssh_socket_set_fd(ssh_socket s, socket_t fd);
socket_t ssh_socket_get_fd(ssh_socket s);
-#ifndef _WIN32
+void ssh_socket_set_connected(ssh_socket s, struct ssh_poll_handle_struct *p);
int ssh_socket_unix(ssh_socket s, const char *path);
void ssh_execute_command(const char *command, socket_t in, socket_t out);
+#ifndef _WIN32
int ssh_socket_connect_proxycommand(ssh_socket s, const char *command);
#endif
void ssh_socket_close(ssh_socket s);
-int ssh_socket_write(ssh_socket s,const void *buffer, int len);
+int ssh_socket_write(ssh_socket s,const void *buffer, uint32_t len);
int ssh_socket_is_open(ssh_socket s);
int ssh_socket_fd_isset(ssh_socket s, fd_set *set);
void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd);
diff --git a/include/libssh/string.h b/include/libssh/string.h
index 8c7db1df..35b2ea2e 100644
--- a/include/libssh/string.h
+++ b/include/libssh/string.h
@@ -22,6 +22,10 @@
#define STRING_H_
#include "libssh/priv.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* must be 32 bits number + immediately our data */
#ifdef _MSC_VER
#pragma pack(1)
@@ -38,4 +42,8 @@ __attribute__ ((packed))
#endif
;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* STRING_H_ */
diff --git a/include/libssh/threads.h b/include/libssh/threads.h
index 522f91d5..47340d17 100644
--- a/include/libssh/threads.h
+++ b/include/libssh/threads.h
@@ -49,6 +49,10 @@
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
int ssh_threads_init(void);
void ssh_threads_finalize(void);
const char *ssh_threads_get_type(void);
@@ -60,4 +64,8 @@ struct ssh_threads_callbacks_struct *ssh_threads_get_default(void);
int crypto_thread_init(struct ssh_threads_callbacks_struct *user_callbacks);
void crypto_thread_finalize(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* THREADS_H_ */
diff --git a/include/libssh/token.h b/include/libssh/token.h
index 9896fb06..550ad792 100644
--- a/include/libssh/token.h
+++ b/include/libssh/token.h
@@ -31,6 +31,10 @@ struct ssh_tokens_st {
char **tokens;
};
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct ssh_tokens_st *ssh_tokenize(const char *chain, char separator);
void ssh_tokens_free(struct ssh_tokens_st *tokens);
@@ -45,4 +49,13 @@ char *ssh_remove_duplicates(const char *list);
char *ssh_append_without_duplicates(const char *list,
const char *appended_list);
+char *ssh_prefix_without_duplicates(const char *list,
+ const char *prefixed_list);
+char *ssh_remove_all_matching(const char *list,
+ const char *remove_list);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* TOKEN_H_ */
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index df6544ee..b3e28eac 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -29,6 +29,10 @@
#include "libssh/libgcrypt.h"
#include "libssh/libmbedcrypto.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum ssh_kdf_digest {
SSH_KDF_SHA1=1,
SSH_KDF_SHA256,
@@ -68,42 +72,42 @@ struct ssh_crypto_struct;
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
-void md5_update(MD5CTX c, const void *data, unsigned long len);
-void md5_final(unsigned char *md,MD5CTX c);
+void md5_ctx_free(MD5CTX);
+int md5_update(MD5CTX c, const void *data, size_t len);
+int md5_final(unsigned char *md, MD5CTX c);
SHACTX sha1_init(void);
-void sha1_update(SHACTX c, const void *data, unsigned long len);
-void sha1_final(unsigned char *md,SHACTX c);
-void sha1(const unsigned char *digest,int len,unsigned char *hash);
+void sha1_ctx_free(SHACTX);
+int sha1_update(SHACTX c, const void *data, size_t len);
+int sha1_final(unsigned char *md,SHACTX c);
+int sha1(const unsigned char *digest,size_t len, unsigned char *hash);
SHA256CTX sha256_init(void);
-void sha256_update(SHA256CTX c, const void *data, unsigned long len);
-void sha256_final(unsigned char *md,SHA256CTX c);
-void sha256(const unsigned char *digest, int len, unsigned char *hash);
+void sha256_ctx_free(SHA256CTX);
+int sha256_update(SHA256CTX c, const void *data, size_t len);
+int sha256_final(unsigned char *md,SHA256CTX c);
+int sha256(const unsigned char *digest, size_t len, unsigned char *hash);
SHA384CTX sha384_init(void);
-void sha384_update(SHA384CTX c, const void *data, unsigned long len);
-void sha384_final(unsigned char *md,SHA384CTX c);
-void sha384(const unsigned char *digest, int len, unsigned char *hash);
+void sha384_ctx_free(SHA384CTX);
+int sha384_update(SHA384CTX c, const void *data, size_t len);
+int sha384_final(unsigned char *md,SHA384CTX c);
+int sha384(const unsigned char *digest, size_t len, unsigned char *hash);
SHA512CTX sha512_init(void);
-void sha512_update(SHA512CTX c, const void *data, unsigned long len);
-void sha512_final(unsigned char *md,SHA512CTX c);
-void sha512(const unsigned char *digest, int len, unsigned char *hash);
-
-void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
-EVPCTX evp_init(int nid);
-void evp_update(EVPCTX ctx, const void *data, unsigned long len);
-void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
-
-HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
-void hmac_update(HMACCTX c, const void *data, unsigned long len);
-void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
+void sha512_ctx_free(SHA512CTX);
+int sha512_update(SHA512CTX c, const void *data, size_t len);
+int sha512_final(unsigned char *md,SHA512CTX c);
+int sha512(const unsigned char *digest, size_t len, unsigned char *hash);
+
+HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type);
+int hmac_update(HMACCTX c, const void *data, size_t len);
+int hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, size_t *len);
size_t hmac_digest_len(enum ssh_hmac_e type);
int ssh_kdf(struct ssh_crypto_struct *crypto,
unsigned char *key, size_t key_len,
- int key_type, unsigned char *output,
+ uint8_t key_type, unsigned char *output,
size_t requested_len);
int crypt_set_algorithms_client(ssh_session session);
@@ -120,4 +124,15 @@ struct ssh_hmac_struct *ssh_get_hmactab(void);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm);
+#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
+int evp_build_pkey(const char* name, OSSL_PARAM_BLD *param_bld, EVP_PKEY **pkey, int selection);
+int evp_dup_dsa_pkey(const ssh_key key, ssh_key new_key, int demote);
+int evp_dup_rsa_pkey(const ssh_key key, ssh_key new_key, int demote);
+int evp_dup_ecdsa_pkey(const ssh_key key, ssh_key new_key, int demote);
+#endif /* HAVE_LIBCRYPTO && OPENSSL_VERSION_NUMBER */
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* WRAPPER_H_ */