diff options
-rw-r--r-- | include/libssh/libssh.h | 1 | ||||
-rw-r--r-- | include/libssh/priv.h | 1 | ||||
-rw-r--r-- | libssh/client.c | 34 | ||||
-rw-r--r-- | libssh/sftp.c | 30 |
4 files changed, 61 insertions, 5 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 5ed2c670..f4dbe126 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -211,6 +211,7 @@ int ssh_connect(SSH_SESSION *session); void ssh_disconnect(SSH_SESSION *session); int ssh_service_request(SSH_SESSION *session, const char *service); char *ssh_get_issue_banner(SSH_SESSION *session); +int ssh_get_openssh_version(SSH_SESSION *session); /* get copyright informations */ const char *ssh_copyright(void); diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 958b0d04..b01b4e93 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -337,6 +337,7 @@ struct ssh_session { int protoversion; int server; int client; + int openssh; u32 send_seq; u32 recv_seq; /* status flags */ diff --git a/libssh/client.c b/libssh/client.c index 5fdec8ee..2ef5568e 100644 --- a/libssh/client.c +++ b/libssh/client.c @@ -98,7 +98,10 @@ char *ssh_get_banner(SSH_SESSION *session) { * @see ssh_get_banner() */ static int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2) { - char *banner = session->serverbanner; + const char *banner = session->serverbanner; + const char *openssh; + + ssh_log(session, SSH_LOG_RARE, "Analyzing banner: %s", banner); if (strncmp(banner, "SSH-", 4) != 0) { ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner); @@ -129,6 +132,17 @@ static int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2) { return -1; } + openssh = strstr(banner, "OpenSSH"); + if (openssh != NULL) { + int major, minor; + major = strtol(openssh + 8, (char **) NULL, 10); + minor = strtol(openssh + 10, (char **) NULL, 10); + session->openssh = SSH_VERSION_INT(major, minor, 0); + ssh_log(session, SSH_LOG_RARE, + "We are talking to an OpenSSH server version: %d.%d (%x)", + major, minor, session->openssh); + } + return 0; } @@ -621,6 +635,24 @@ char *ssh_get_issue_banner(SSH_SESSION *session) { } /** + * @brief Get the version of the OpenSSH server, if it is not an OpenSSH server + * then 0 will be returned. + * + * You can use the SSH_VERSION_INT macro to compare version numbers. + * + * @param session The SSH session to use. + * + * @return The version number if available, 0 otherwise. + */ +int ssh_get_openssh_version(SSH_SESSION *session) { + if (session == NULL) { + return 0; + } + + return session->openssh; +} + +/** * @brief Disconnect from a session (client or server). * * @param session The SSH session to disconnect. diff --git a/libssh/sftp.c b/libssh/sftp.c index e86a262b..f720aa58 100644 --- a/libssh/sftp.c +++ b/libssh/sftp.c @@ -2243,10 +2243,32 @@ int sftp_symlink(SFTP_SESSION *sftp, const char *target, const char *dest) { } id = sftp_get_new_id(sftp); - if (buffer_add_u32(buffer, id) < 0 || - buffer_add_ssh_string(buffer, target_s) < 0 || - buffer_add_ssh_string(buffer, dest_s) < 0 || - sftp_packet_write(sftp, SSH_FXP_SYMLINK, buffer) < 0) { + if (buffer_add_u32(buffer, id) < 0) { + buffer_free(buffer); + string_free(dest_s); + string_free(target_s); + return -1; + } + if (ssh_get_openssh_version(sftp->session)) { + /* TODO check for version number if they ever fix it. */ + if (buffer_add_ssh_string(buffer, target_s) < 0 || + buffer_add_ssh_string(buffer, dest_s) < 0) { + buffer_free(buffer); + string_free(dest_s); + string_free(target_s); + return -1; + } + } else { + if (buffer_add_ssh_string(buffer, dest_s) < 0 || + buffer_add_ssh_string(buffer, target_s) < 0) { + buffer_free(buffer); + string_free(dest_s); + string_free(target_s); + return -1; + } + } + + if (sftp_packet_write(sftp, SSH_FXP_SYMLINK, buffer) < 0) { buffer_free(buffer); string_free(dest_s); string_free(target_s); |