diff --git a/include/libssh/session.h b/include/libssh/session.h index 44e95298..3bb8ff44 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -89,6 +89,9 @@ enum ssh_pending_call_e { #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 +/* The scp on server can not handle quoted paths. Skip the mitigation for + * CVE-2019-14889 when using scp */ +#define SSH_SESSION_FLAG_SCP_QUOTING_BROKEN 0x0040 /* codes to use with ssh_handle_packets*() */ /* Infinite timeout */ diff --git a/src/misc.c b/src/misc.c index c2bb5484..13f7b9dd 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1376,6 +1376,7 @@ int ssh_analyze_banner(ssh_session session, int server) { const char *banner = NULL; const char *openssh = NULL; + const char *ios = NULL; if (server) { banner = session->clientbanner; @@ -1465,6 +1466,11 @@ int ssh_analyze_banner(ssh_session session, int server) major, minor, session->openssh); } } + /* Cisco devices have odd scp implementation which breaks */ + ios = strstr(banner, "Cisco"); + if (ios != NULL) { + session->flags |= SSH_SESSION_FLAG_SCP_QUOTING_BROKEN; + } done: return 0; diff --git a/src/scp.c b/src/scp.c index a1e3687f..fb29d0c6 100644 --- a/src/scp.c +++ b/src/scp.c @@ -30,6 +30,7 @@ #include "libssh/priv.h" #include "libssh/scp.h" #include "libssh/misc.h" +#include "libssh/session.h" /** * @defgroup libssh_scp The SSH scp functions @@ -197,6 +198,17 @@ int ssh_scp_init(ssh_scp scp) return SSH_ERROR; } + /* Some servers do not handle the quoting well. Pass in the raw file + * location */ + if (scp->session->flags & SSH_SESSION_FLAG_SCP_QUOTING_BROKEN) { + free(quoted_location); + quoted_location = strdup(scp->location); + if (quoted_location == NULL) { + ssh_set_error_oom(scp->session); + return SSH_ERROR; + } + } + if (scp->mode == SSH_SCP_WRITE) { snprintf(execbuffer, sizeof(execbuffer), "scp -t %s %s", scp->recursive ? "-r" : "", quoted_location);