diff --git a/0001-CVE-2019-14889.patch b/0001-CVE-2019-14889.patch deleted file mode 100644 index b2f0753a1e18eacfb97dc58d73178f2beae2aed5..0000000000000000000000000000000000000000 --- a/0001-CVE-2019-14889.patch +++ /dev/null @@ -1,1390 +0,0 @@ -From 4aea835974996b2deb011024c53f4ff4329a95b5 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Thu, 31 Oct 2019 17:56:34 +0100 -Subject: CVE-2019-14889: scp: Reformat scp.c - -Fixes T181 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider -(cherry picked from commit 42c727d0c186a1e2fa84a31ab40e16e58b404ab3) ---- - src/scp.c | 1200 +++++++++++++++++++++++++++++++++++-------------------------- - 1 file changed, 698 insertions(+), 502 deletions(-) - -diff --git a/src/scp.c b/src/scp.c -index fd9aaaaa..5de0e6ff 100644 ---- a/src/scp.c -+++ b/src/scp.c -@@ -57,30 +57,47 @@ - * - * @returns A ssh_scp handle, NULL if the creation was impossible. - */ --ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){ -- ssh_scp scp=malloc(sizeof(struct ssh_scp_struct)); -- if(scp == NULL){ -- ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp"); -- return NULL; -- } -- ZERO_STRUCTP(scp); -- if((mode&~SSH_SCP_RECURSIVE) != SSH_SCP_WRITE && (mode &~SSH_SCP_RECURSIVE) != SSH_SCP_READ){ -- ssh_set_error(session,SSH_FATAL,"Invalid mode %d for ssh_scp_new()",mode); -- ssh_scp_free(scp); -- return NULL; -- } -- scp->location=strdup(location); -- if (scp->location == NULL) { -- ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp"); -+ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location) -+{ -+ ssh_scp scp = NULL; -+ -+ if (session == NULL) { -+ goto error; -+ } -+ -+ scp = (ssh_scp)calloc(1, sizeof(struct ssh_scp_struct)); -+ if (scp == NULL) { -+ ssh_set_error(session, SSH_FATAL, -+ "Error allocating memory for ssh_scp"); -+ goto error; -+ } -+ -+ if ((mode & ~SSH_SCP_RECURSIVE) != SSH_SCP_WRITE && -+ (mode & ~SSH_SCP_RECURSIVE) != SSH_SCP_READ) -+ { -+ ssh_set_error(session, SSH_FATAL, -+ "Invalid mode %d for ssh_scp_new()", mode); -+ goto error; -+ } -+ -+ scp->location = strdup(location); -+ if (scp->location == NULL) { -+ ssh_set_error(session, SSH_FATAL, -+ "Error allocating memory for ssh_scp"); -+ goto error; -+ } -+ -+ scp->session = session; -+ scp->mode = mode & ~SSH_SCP_RECURSIVE; -+ scp->recursive = (mode & SSH_SCP_RECURSIVE) != 0; -+ scp->channel = NULL; -+ scp->state = SSH_SCP_NEW; -+ -+ return scp; -+ -+error: - ssh_scp_free(scp); - return NULL; -- } -- scp->session=session; -- scp->mode=mode & ~SSH_SCP_RECURSIVE; -- scp->recursive = (mode & SSH_SCP_RECURSIVE) != 0; -- scp->channel=NULL; -- scp->state=SSH_SCP_NEW; -- return scp; - } - - /** -@@ -94,59 +111,78 @@ ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){ - */ - int ssh_scp_init(ssh_scp scp) - { -- int r; -- char execbuffer[1024]; -- uint8_t code; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_NEW){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state"); -- return SSH_ERROR; -- } -- SSH_LOG(SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'", -- scp->mode==SSH_SCP_WRITE?"write":"read", -- scp->recursive?"recursive ":"", -- scp->location); -- scp->channel=ssh_channel_new(scp->session); -- if(scp->channel == NULL){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- r= ssh_channel_open_session(scp->channel); -- if(r==SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(scp->mode == SSH_SCP_WRITE) -- snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s", -- scp->recursive ? "-r":"", scp->location); -- else -- snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s", -- scp->recursive ? "-r":"", scp->location); -- if(ssh_channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(scp->mode == SSH_SCP_WRITE){ -- r=ssh_channel_read(scp->channel,&code,1,0); -- if(r<=0){ -- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(code != 0){ -- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- } else { -- ssh_channel_write(scp->channel,"",1); -- } -- if(scp->mode == SSH_SCP_WRITE) -- scp->state=SSH_SCP_WRITE_INITED; -- else -- scp->state=SSH_SCP_READ_INITED; -- return SSH_OK; -+ int rc; -+ char execbuffer[1024] = {0}; -+ uint8_t code; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_NEW) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_init called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ SSH_LOG(SSH_LOG_PROTOCOL, -+ "Initializing scp session %s %son location '%s'", -+ scp->mode == SSH_SCP_WRITE?"write":"read", -+ scp->recursive?"recursive ":"", -+ scp->location); -+ -+ scp->channel = ssh_channel_new(scp->session); -+ if (scp->channel == NULL) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_open_session(scp->channel); -+ if (rc == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (scp->mode == SSH_SCP_WRITE) { -+ snprintf(execbuffer, sizeof(execbuffer), "scp -t %s %s", -+ scp->recursive ? "-r":"", scp->location); -+ } else { -+ snprintf(execbuffer, sizeof(execbuffer), "scp -f %s %s", -+ scp->recursive ? "-r":"", scp->location); -+ } -+ -+ if (ssh_channel_request_exec(scp->channel, execbuffer) == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (scp->mode == SSH_SCP_WRITE) { -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc <= 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Error reading status code: %s", -+ ssh_get_error(scp->session)); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (code != 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "scp status code %ud not valid", code); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ } else { -+ ssh_channel_write(scp->channel, "", 1); -+ } -+ -+ if (scp->mode == SSH_SCP_WRITE) { -+ scp->state = SSH_SCP_WRITE_INITED; -+ } else { -+ scp->state = SSH_SCP_READ_INITED; -+ } -+ -+ return SSH_OK; - } - - /** -@@ -160,33 +196,40 @@ int ssh_scp_init(ssh_scp scp) - */ - int ssh_scp_close(ssh_scp scp) - { -- char buffer[128]; -- int err; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->channel != NULL){ -- if(ssh_channel_send_eof(scp->channel) == SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- /* avoid situations where data are buffered and -- * not yet stored on disk. This can happen if the close is sent -- * before we got the EOF back -- */ -- while(!ssh_channel_is_eof(scp->channel)){ -- err=ssh_channel_read(scp->channel,buffer,sizeof(buffer),0); -- if(err==SSH_ERROR || err==0) -- break; -+ char buffer[128] = {0}; -+ int rc; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; - } -- if(ssh_channel_close(scp->channel) == SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -+ -+ if (scp->channel != NULL) { -+ if (ssh_channel_send_eof(scp->channel) == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ /* avoid situations where data are buffered and -+ * not yet stored on disk. This can happen if the close is sent -+ * before we got the EOF back -+ */ -+ while (!ssh_channel_is_eof(scp->channel)) { -+ rc = ssh_channel_read(scp->channel, buffer, sizeof(buffer), 0); -+ if (rc == SSH_ERROR || rc == 0) { -+ break; -+ } -+ } -+ -+ if (ssh_channel_close(scp->channel) == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ ssh_channel_free(scp->channel); -+ scp->channel = NULL; - } -- ssh_channel_free(scp->channel); -- scp->channel=NULL; -- } -- scp->state=SSH_SCP_NEW; -- return SSH_OK; -+ -+ scp->state = SSH_SCP_NEW; -+ return SSH_OK; - } - - /** -@@ -198,16 +241,22 @@ int ssh_scp_close(ssh_scp scp) - */ - void ssh_scp_free(ssh_scp scp) - { -- if(scp==NULL) -- return; -- if(scp->state != SSH_SCP_NEW) -- ssh_scp_close(scp); -- if(scp->channel) -- ssh_channel_free(scp->channel); -- SAFE_FREE(scp->location); -- SAFE_FREE(scp->request_name); -- SAFE_FREE(scp->warning); -- SAFE_FREE(scp); -+ if (scp == NULL) { -+ return; -+ } -+ -+ if (scp->state != SSH_SCP_NEW) { -+ ssh_scp_close(scp); -+ } -+ -+ if (scp->channel) { -+ ssh_channel_free(scp->channel); -+ } -+ -+ SAFE_FREE(scp->location); -+ SAFE_FREE(scp->request_name); -+ SAFE_FREE(scp->warning); -+ SAFE_FREE(scp); - } - - /** -@@ -224,81 +273,106 @@ void ssh_scp_free(ssh_scp scp) - * - * @see ssh_scp_leave_directory() - */ --int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){ -- char buffer[1024]; -- int r; -- uint8_t code; -- char *dir; -- char *perms; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_WRITE_INITED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state"); -- return SSH_ERROR; -- } -- dir=ssh_basename(dirname); -- perms=ssh_scp_string_mode(mode); -- snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir); -- SAFE_FREE(dir); -- SAFE_FREE(perms); -- r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); -- if(r==SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- r=ssh_channel_read(scp->channel,&code,1,0); -- if(r<=0){ -- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(code != 0){ -- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- return SSH_OK; -+int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode) -+{ -+ char buffer[1024] = {0}; -+ int rc; -+ uint8_t code; -+ char *dir = NULL; -+ char *perms = NULL; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_WRITE_INITED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_push_directory called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ dir = ssh_basename(dirname); -+ perms = ssh_scp_string_mode(mode); -+ snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir); -+ SAFE_FREE(dir); -+ SAFE_FREE(perms); -+ -+ rc = ssh_channel_write(scp->channel, buffer, strlen(buffer)); -+ if (rc == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc <= 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Error reading status code: %s", -+ ssh_get_error(scp->session)); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (code != 0) { -+ ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid", -+ code); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ return SSH_OK; - } - - /** - * @brief Leave a directory. - * -- * @returns SSH_OK if the directory has been left,SSH_ERROR if an -+ * @returns SSH_OK if the directory has been left, SSH_ERROR if an - * error occured. - * - * @see ssh_scp_push_directory() - */ -- int ssh_scp_leave_directory(ssh_scp scp){ -- char buffer[]="E\n"; -- int r; -- uint8_t code; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_WRITE_INITED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_leave_directory called under invalid state"); -- return SSH_ERROR; -- } -- r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); -- if(r==SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- r=ssh_channel_read(scp->channel,&code,1,0); -- if(r<=0){ -- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(code != 0){ -- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- return SSH_OK; -+int ssh_scp_leave_directory(ssh_scp scp) -+{ -+ char buffer[] = "E\n"; -+ int rc; -+ uint8_t code; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_WRITE_INITED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_leave_directory called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_write(scp->channel, buffer, strlen(buffer)); -+ if (rc == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc <= 0) { -+ ssh_set_error(scp->session, SSH_FATAL, "Error reading status code: %s", -+ ssh_get_error(scp->session)); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (code != 0) { -+ ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid", -+ code); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ return SSH_OK; - } - - /** -- * @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit size. -+ * @brief Initialize the sending of a file to a scp in sink mode, using a 64-bit -+ * size. - * - * @param[in] scp The scp handle. - * -@@ -314,44 +388,61 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){ - * - * @see ssh_scp_push_file() - */ --int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mode){ -- char buffer[1024]; -- int r; -- uint8_t code; -- char *file; -- char *perms; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_WRITE_INITED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state"); -- return SSH_ERROR; -- } -- file=ssh_basename(filename); -- perms=ssh_scp_string_mode(mode); -- SSH_LOG(SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIu64 " with permissions '%s'",file,size,perms); -- snprintf(buffer, sizeof(buffer), "C%s %" PRIu64 " %s\n", perms, size, file); -- SAFE_FREE(file); -- SAFE_FREE(perms); -- r=ssh_channel_write(scp->channel,buffer,strlen(buffer)); -- if(r==SSH_ERROR){ -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- r=ssh_channel_read(scp->channel,&code,1,0); -- if(r<=0){ -- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session)); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- if(code != 0){ -- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- scp->filelen = size; -- scp->processed = 0; -- scp->state=SSH_SCP_WRITE_WRITING; -- return SSH_OK; -+int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, -+ int mode) -+{ -+ char buffer[1024] = {0}; -+ int rc; -+ char *file = NULL; -+ char *perms = NULL; -+ uint8_t code; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_WRITE_INITED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_push_file called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ file = ssh_basename(filename); -+ perms = ssh_scp_string_mode(mode); -+ SSH_LOG(SSH_LOG_PROTOCOL, -+ "SCP pushing file %s, size %" PRIu64 " with permissions '%s'", -+ file, size, perms); -+ snprintf(buffer, sizeof(buffer), "C%s %" PRIu64 " %s\n", perms, size, file); -+ SAFE_FREE(file); -+ SAFE_FREE(perms); -+ -+ rc = ssh_channel_write(scp->channel, buffer, strlen(buffer)); -+ if (rc == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc <= 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Error reading status code: %s", -+ ssh_get_error(scp->session)); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ if (code != 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "scp status code %ud not valid", code); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ scp->filelen = size; -+ scp->processed = 0; -+ scp->state = SSH_SCP_WRITE_WRITING; -+ -+ return SSH_OK; - } - - /** -@@ -369,8 +460,9 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, int mo - * @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an - * error occured. - */ --int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){ -- return ssh_scp_push_file64(scp, filename, (uint64_t) size, mode); -+int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode) -+{ -+ return ssh_scp_push_file64(scp, filename, (uint64_t) size, mode); - } - - /** -@@ -385,41 +477,60 @@ int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){ - * - * @returns The return code, SSH_ERROR a error occured. - */ --int ssh_scp_response(ssh_scp scp, char **response){ -- unsigned char code; -- int r; -- char msg[128]; -- if(scp==NULL) -- return SSH_ERROR; -- r=ssh_channel_read(scp->channel,&code,1,0); -- if(r == SSH_ERROR) -- return SSH_ERROR; -- if(code == 0) -- return 0; -- if(code > 2){ -- ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code); -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- r=ssh_scp_read_string(scp,msg,sizeof(msg)); -- if(r==SSH_ERROR) -- return r; -- /* Warning */ -- if(code == 1){ -- ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg); -- SSH_LOG(SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg); -- if(response) -- *response=strdup(msg); -- return 1; -- } -- if(code == 2){ -- ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg); -- if(response) -- *response=strdup(msg); -- return 2; -- } -- /* Not reached */ -- return SSH_ERROR; -+int ssh_scp_response(ssh_scp scp, char **response) -+{ -+ unsigned char code; -+ int rc; -+ char msg[128] = {0}; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc == SSH_ERROR) { -+ return SSH_ERROR; -+ } -+ -+ if (code == 0) { -+ return 0; -+ } -+ -+ if (code > 2) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "SCP: invalid status code %ud received", code); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_scp_read_string(scp, msg, sizeof(msg)); -+ if (rc == SSH_ERROR) { -+ return rc; -+ } -+ -+ /* Warning */ -+ if (code == 1) { -+ ssh_set_error(scp->session, SSH_REQUEST_DENIED, -+ "SCP: Warning: status code 1 received: %s", msg); -+ SSH_LOG(SSH_LOG_RARE, -+ "SCP: Warning: status code 1 received: %s", msg); -+ if (response) { -+ *response = strdup(msg); -+ } -+ return 1; -+ } -+ -+ if (code == 2) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "SCP: Error: status code 2 received: %s", msg); -+ if (response) { -+ *response = strdup(msg); -+ } -+ return 2; -+ } -+ -+ /* Not reached */ -+ return SSH_ERROR; - } - - /** -@@ -434,57 +545,72 @@ int ssh_scp_response(ssh_scp scp, char **response){ - * @returns SSH_OK if the write was successful, SSH_ERROR an error - * occured while writing. - */ --int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ -- int w; -- int r; -- uint8_t code; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_WRITE_WRITING){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state"); -- return SSH_ERROR; -- } -- if(scp->processed + len > scp->filelen) -- len = (size_t) (scp->filelen - scp->processed); -- /* hack to avoid waiting for window change */ -- r = ssh_channel_poll(scp->channel, 0); -- if (r == SSH_ERROR) { -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- w=ssh_channel_write(scp->channel,buffer,len); -- if(w != SSH_ERROR) -- scp->processed += w; -- else { -- scp->state=SSH_SCP_ERROR; -- //return=channel_get_exit_status(scp->channel); -- return SSH_ERROR; -- } -- /* Far end sometimes send a status message, which we need to read -- * and handle */ -- r = ssh_channel_poll(scp->channel,0); -- if(r > 0){ -- r = ssh_channel_read(scp->channel, &code, 1, 0); -- if(r == SSH_ERROR){ -- return SSH_ERROR; -- } -- if(code == 1 || code == 2){ -- ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Error: status code %i received", code); -- return SSH_ERROR; -- } -- } -- /* Check if we arrived at end of file */ -- if(scp->processed == scp->filelen) { -- code = 0; -- w = ssh_channel_write(scp->channel, &code, 1); -- if(w == SSH_ERROR){ -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- scp->processed=scp->filelen=0; -- scp->state=SSH_SCP_WRITE_INITED; -- } -- return SSH_OK; -+int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len) -+{ -+ int w; -+ int rc; -+ uint8_t code; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_WRITE_WRITING) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_write called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ if (scp->processed + len > scp->filelen) { -+ len = (size_t) (scp->filelen - scp->processed); -+ } -+ -+ /* hack to avoid waiting for window change */ -+ rc = ssh_channel_poll(scp->channel, 0); -+ if (rc == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ w = ssh_channel_write(scp->channel, buffer, len); -+ if (w != SSH_ERROR) { -+ scp->processed += w; -+ } else { -+ scp->state = SSH_SCP_ERROR; -+ //return = channel_get_exit_status(scp->channel); -+ return SSH_ERROR; -+ } -+ -+ /* Far end sometimes send a status message, which we need to read -+ * and handle */ -+ rc = ssh_channel_poll(scp->channel, 0); -+ if (rc > 0) { -+ rc = ssh_channel_read(scp->channel, &code, 1, 0); -+ if (rc == SSH_ERROR) { -+ return SSH_ERROR; -+ } -+ -+ if (code == 1 || code == 2) { -+ ssh_set_error(scp->session, SSH_REQUEST_DENIED, -+ "SCP: Error: status code %i received", code); -+ return SSH_ERROR; -+ } -+ } -+ -+ /* Check if we arrived at end of file */ -+ if (scp->processed == scp->filelen) { -+ code = 0; -+ w = ssh_channel_write(scp->channel, &code, 1); -+ if (w == SSH_ERROR) { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ scp->processed = scp->filelen = 0; -+ scp->state = SSH_SCP_WRITE_INITED; -+ } -+ -+ return SSH_OK; - } - - /** -@@ -501,27 +627,36 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ - * @returns SSH_OK if the string was read, SSH_ERROR if an error - * occured while reading. - */ --int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len){ -- size_t r=0; -- int err=SSH_OK; -- if(scp==NULL) -- return SSH_ERROR; -- while(rchannel,&buffer[r],1,0); -- if(err==SSH_ERROR){ -- break; -- } -- if(err==0){ -- ssh_set_error(scp->session,SSH_FATAL,"End of file while reading string"); -- err=SSH_ERROR; -- break; -- } -- r++; -- if(buffer[r-1] == '\n') -- break; -- } -- buffer[r]=0; -- return err; -+int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len) -+{ -+ size_t read = 0; -+ int err = SSH_OK; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ while (read < len - 1) { -+ err = ssh_channel_read(scp->channel, &buffer[read], 1, 0); -+ if (err == SSH_ERROR) { -+ break; -+ } -+ -+ if (err == 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "End of file while reading string"); -+ err = SSH_ERROR; -+ break; -+ } -+ -+ read++; -+ if (buffer[read - 1] == '\n') { -+ break; -+ } -+ } -+ -+ buffer[read] = 0; -+ return err; - } - - /** -@@ -544,90 +679,105 @@ int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len){ - * @see ssh_scp_accept_request() - * @see ssh_scp_request_get_warning() - */ --int ssh_scp_pull_request(ssh_scp scp){ -- char buffer[MAX_BUF_SIZE] = {0}; -- char *mode=NULL; -- char *p,*tmp; -- uint64_t size; -- char *name=NULL; -- int err; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_READ_INITED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state"); -- return SSH_ERROR; -- } -- err=ssh_scp_read_string(scp,buffer,sizeof(buffer)); -- if(err==SSH_ERROR){ -- if(ssh_channel_is_eof(scp->channel)){ -- scp->state=SSH_SCP_TERMINATED; -- return SSH_SCP_REQUEST_EOF; -- } -- return err; -- } -- p=strchr(buffer,'\n'); -- if(p!=NULL) -- *p='\0'; -- SSH_LOG(SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer); -- switch(buffer[0]){ -+int ssh_scp_pull_request(ssh_scp scp) -+{ -+ char buffer[MAX_BUF_SIZE] = {0}; -+ char *mode = NULL; -+ char *p, *tmp; -+ uint64_t size; -+ char *name = NULL; -+ int rc; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_READ_INITED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_pull_request called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_scp_read_string(scp, buffer, sizeof(buffer)); -+ if (rc == SSH_ERROR) { -+ if (ssh_channel_is_eof(scp->channel)) { -+ scp->state = SSH_SCP_TERMINATED; -+ return SSH_SCP_REQUEST_EOF; -+ } -+ return rc; -+ } -+ -+ p = strchr(buffer, '\n'); -+ if (p != NULL) { -+ *p = '\0'; -+ } -+ -+ SSH_LOG(SSH_LOG_PROTOCOL, "Received SCP request: '%s'", buffer); -+ switch(buffer[0]) { - case 'C': -- /* File */ -+ /* File */ - case 'D': -- /* Directory */ -- p=strchr(buffer,' '); -- if(p==NULL) -- goto error; -- *p='\0'; -- p++; -- //mode=strdup(&buffer[1]); -- scp->request_mode=ssh_scp_integer_mode(&buffer[1]); -- tmp=p; -- p=strchr(p,' '); -- if(p==NULL) -- goto error; -- *p=0; -- size = strtoull(tmp,NULL,10); -- p++; -- name=strdup(p); -- SAFE_FREE(scp->request_name); -- scp->request_name=name; -- if(buffer[0]=='C'){ -- scp->filelen=size; -- scp->request_type=SSH_SCP_REQUEST_NEWFILE; -- } else { -- scp->filelen='0'; -- scp->request_type=SSH_SCP_REQUEST_NEWDIR; -- } -- scp->state=SSH_SCP_READ_REQUESTED; -- scp->processed = 0; -- return scp->request_type; -- break; -+ /* Directory */ -+ p = strchr(buffer, ' '); -+ if (p == NULL) { -+ goto error; -+ } -+ *p = '\0'; -+ p++; -+ //mode = strdup(&buffer[1]); -+ scp->request_mode = ssh_scp_integer_mode(&buffer[1]); -+ tmp = p; -+ p = strchr(p, ' '); -+ if (p == NULL) { -+ goto error; -+ } -+ *p = 0; -+ size = strtoull(tmp, NULL, 10); -+ p++; -+ name = strdup(p); -+ SAFE_FREE(scp->request_name); -+ scp->request_name = name; -+ if (buffer[0] == 'C') { -+ scp->filelen = size; -+ scp->request_type = SSH_SCP_REQUEST_NEWFILE; -+ } else { -+ scp->filelen = '0'; -+ scp->request_type = SSH_SCP_REQUEST_NEWDIR; -+ } -+ scp->state = SSH_SCP_READ_REQUESTED; -+ scp->processed = 0; -+ return scp->request_type; -+ break; - case 'E': -- scp->request_type=SSH_SCP_REQUEST_ENDDIR; -- ssh_channel_write(scp->channel,"",1); -- return scp->request_type; -+ scp->request_type = SSH_SCP_REQUEST_ENDDIR; -+ ssh_channel_write(scp->channel, "", 1); -+ return scp->request_type; - case 0x1: -- ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]); -- scp->request_type=SSH_SCP_REQUEST_WARNING; -- SAFE_FREE(scp->warning); -- scp->warning=strdup(&buffer[1]); -- return scp->request_type; -+ ssh_set_error(scp->session, SSH_REQUEST_DENIED, -+ "SCP: Warning: %s", &buffer[1]); -+ scp->request_type = SSH_SCP_REQUEST_WARNING; -+ SAFE_FREE(scp->warning); -+ scp->warning = strdup(&buffer[1]); -+ return scp->request_type; - case 0x2: -- ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]); -- return SSH_ERROR; -+ ssh_set_error(scp->session, SSH_FATAL, -+ "SCP: Error: %s", &buffer[1]); -+ return SSH_ERROR; - case 'T': -- /* Timestamp */ -+ /* Timestamp */ - default: -- ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer); -- return SSH_ERROR; -- } -- -- /* a parsing error occured */ -- error: -- SAFE_FREE(name); -- SAFE_FREE(mode); -- ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer); -- return SSH_ERROR; -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Unhandled message: (%d)%s", buffer[0], buffer); -+ return SSH_ERROR; -+ } -+ -+ /* a parsing error occured */ -+error: -+ SAFE_FREE(name); -+ SAFE_FREE(mode); -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Parsing error while parsing message: %s", buffer); -+ return SSH_ERROR; - } - - /** -@@ -641,24 +791,31 @@ int ssh_scp_pull_request(ssh_scp scp){ - * @returns SSH_OK if the message was sent, SSH_ERROR if the sending - * the message failed, or sending it in a bad state. - */ --int ssh_scp_deny_request(ssh_scp scp, const char *reason){ -- char buffer[MAX_BUF_SIZE]; -- int err; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_READ_REQUESTED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); -- return SSH_ERROR; -- } -- snprintf(buffer,sizeof(buffer),"%c%s\n",2,reason); -- err=ssh_channel_write(scp->channel,buffer,strlen(buffer)); -- if(err==SSH_ERROR) { -- return SSH_ERROR; -- } -- else { -- scp->state=SSH_SCP_READ_INITED; -- return SSH_OK; -- } -+int ssh_scp_deny_request(ssh_scp scp, const char *reason) -+{ -+ char buffer[MAX_BUF_SIZE] = {0}; -+ int rc; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_READ_REQUESTED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_deny_request called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ snprintf(buffer, sizeof(buffer), "%c%s\n", 2, reason); -+ rc = ssh_channel_write(scp->channel, buffer, strlen(buffer)); -+ if (rc == SSH_ERROR) { -+ return SSH_ERROR; -+ } -+ -+ else { -+ scp->state = SSH_SCP_READ_INITED; -+ return SSH_OK; -+ } - } - - /** -@@ -670,24 +827,32 @@ int ssh_scp_deny_request(ssh_scp scp, const char *reason){ - * @returns SSH_OK if the message was sent, SSH_ERROR if sending the - * message failed, or sending it in a bad state. - */ --int ssh_scp_accept_request(ssh_scp scp){ -- char buffer[]={0x00}; -- int err; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state != SSH_SCP_READ_REQUESTED){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state"); -- return SSH_ERROR; -- } -- err=ssh_channel_write(scp->channel,buffer,1); -- if(err==SSH_ERROR) { -- return SSH_ERROR; -- } -- if(scp->request_type==SSH_SCP_REQUEST_NEWFILE) -- scp->state=SSH_SCP_READ_READING; -- else -- scp->state=SSH_SCP_READ_INITED; -- return SSH_OK; -+int ssh_scp_accept_request(ssh_scp scp) -+{ -+ char buffer[] = {0x00}; -+ int rc; -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state != SSH_SCP_READ_REQUESTED) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_deny_request called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_channel_write(scp->channel, buffer, 1); -+ if (rc == SSH_ERROR) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->request_type == SSH_SCP_REQUEST_NEWFILE) { -+ scp->state = SSH_SCP_READ_READING; -+ } else { -+ scp->state = SSH_SCP_READ_INITED; -+ } -+ -+ return SSH_OK; - } - - /** @brief Read from a remote scp file -@@ -700,48 +865,64 @@ int ssh_scp_accept_request(ssh_scp scp){ - * @returns The nNumber of bytes read, SSH_ERROR if an error occured - * while reading. - */ --int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){ -- int r; -- int code; -- if(scp==NULL) -- return SSH_ERROR; -- if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){ -- r=ssh_scp_accept_request(scp); -- if(r==SSH_ERROR) -- return r; -- } -- if(scp->state != SSH_SCP_READ_READING){ -- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state"); -- return SSH_ERROR; -- } -- if(scp->processed + size > scp->filelen) -- size = (size_t) (scp->filelen - scp->processed); -- if(size > 65536) -- size=65536; /* avoid too large reads */ -- r=ssh_channel_read(scp->channel,buffer,size,0); -- if(r != SSH_ERROR) -- scp->processed += r; -- else { -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- /* Check if we arrived at end of file */ -- if(scp->processed == scp->filelen) { -- scp->processed=scp->filelen=0; -- ssh_channel_write(scp->channel,"",1); -- code=ssh_scp_response(scp,NULL); -- if(code == 0){ -- scp->state=SSH_SCP_READ_INITED; -- return r; -- } -- if(code==1){ -- scp->state=SSH_SCP_READ_INITED; -- return SSH_ERROR; -- } -- scp->state=SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- return r; -+int ssh_scp_read(ssh_scp scp, void *buffer, size_t size) -+{ -+ int rc; -+ int code; -+ -+ if (scp == NULL) { -+ return SSH_ERROR; -+ } -+ -+ if (scp->state == SSH_SCP_READ_REQUESTED && -+ scp->request_type == SSH_SCP_REQUEST_NEWFILE) -+ { -+ rc = ssh_scp_accept_request(scp); -+ if (rc == SSH_ERROR) { -+ return rc; -+ } -+ } -+ -+ if (scp->state != SSH_SCP_READ_READING) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "ssh_scp_read called under invalid state"); -+ return SSH_ERROR; -+ } -+ -+ if (scp->processed + size > scp->filelen) { -+ size = (size_t) (scp->filelen - scp->processed); -+ } -+ -+ if (size > 65536) { -+ size = 65536; /* avoid too large reads */ -+ } -+ -+ rc = ssh_channel_read(scp->channel, buffer, size, 0); -+ if (rc != SSH_ERROR) { -+ scp->processed += rc; -+ } else { -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ /* Check if we arrived at end of file */ -+ if (scp->processed == scp->filelen) { -+ scp->processed = scp->filelen = 0; -+ ssh_channel_write(scp->channel, "", 1); -+ code = ssh_scp_response(scp, NULL); -+ if (code == 0) { -+ scp->state = SSH_SCP_READ_INITED; -+ return rc; -+ } -+ if (code == 1) { -+ scp->state = SSH_SCP_READ_INITED; -+ return SSH_ERROR; -+ } -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ return rc; - } - - /** -@@ -751,10 +932,13 @@ int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){ - * @returns The file name, NULL on error. The string should not be - * freed. - */ --const char *ssh_scp_request_get_filename(ssh_scp scp){ -- if(scp==NULL) -- return NULL; -- return scp->request_name; -+const char *ssh_scp_request_get_filename(ssh_scp scp) -+{ -+ if (scp == NULL) { -+ return NULL; -+ } -+ -+ return scp->request_name; - } - - /** -@@ -763,10 +947,13 @@ const char *ssh_scp_request_get_filename(ssh_scp scp){ - * - * @returns The UNIX permission, e.g 0644, -1 on error. - */ --int ssh_scp_request_get_permissions(ssh_scp scp){ -- if(scp==NULL) -- return -1; -- return scp->request_mode; -+int ssh_scp_request_get_permissions(ssh_scp scp) -+{ -+ if (scp == NULL) { -+ return -1; -+ } -+ -+ return scp->request_mode; - } - - /** @brief Get the size of the file being pushed from the other party. -@@ -776,20 +963,24 @@ int ssh_scp_request_get_permissions(ssh_scp scp){ - * be truncated. - * @see ssh_scp_request_get_size64() - */ --size_t ssh_scp_request_get_size(ssh_scp scp){ -- if(scp==NULL) -- return 0; -- return (size_t)scp->filelen; -+size_t ssh_scp_request_get_size(ssh_scp scp) -+{ -+ if (scp == NULL) { -+ return 0; -+ } -+ return (size_t)scp->filelen; - } - - /** @brief Get the size of the file being pushed from the other party. - * - * @returns The numeric size of the file being read. - */ --uint64_t ssh_scp_request_get_size64(ssh_scp scp){ -- if(scp==NULL) -- return 0; -- return scp->filelen; -+uint64_t ssh_scp_request_get_size64(ssh_scp scp) -+{ -+ if (scp == NULL) { -+ return 0; -+ } -+ return scp->filelen; - } - - /** -@@ -799,9 +990,10 @@ uint64_t ssh_scp_request_get_size64(ssh_scp scp){ - * - * @returns An integer value, e.g. 420 for "0644". - */ --int ssh_scp_integer_mode(const char *mode){ -- int value=strtoul(mode,NULL,8) & 0xffff; -- return value; -+int ssh_scp_integer_mode(const char *mode) -+{ -+ int value = strtoul(mode, NULL, 8) & 0xffff; -+ return value; - } - - /** -@@ -812,10 +1004,11 @@ int ssh_scp_integer_mode(const char *mode){ - * @returns A pointer to a malloc'ed string containing the scp mode, - * e.g. "0644". - */ --char *ssh_scp_string_mode(int mode){ -- char buffer[16]; -- snprintf(buffer,sizeof(buffer),"%.4o",mode); -- return strdup(buffer); -+char *ssh_scp_string_mode(int mode) -+{ -+ char buffer[16] = {0}; -+ snprintf(buffer, sizeof(buffer), "%.4o", mode); -+ return strdup(buffer); - } - - /** -@@ -826,10 +1019,13 @@ char *ssh_scp_string_mode(int mode){ - * @returns A warning string, or NULL on error. The string should - * not be freed. - */ --const char *ssh_scp_request_get_warning(ssh_scp scp){ -- if(scp==NULL) -- return NULL; -- return scp->warning; -+const char *ssh_scp_request_get_warning(ssh_scp scp) -+{ -+ if (scp == NULL) { -+ return NULL; -+ } -+ -+ return scp->warning; - } - - /** @} */ --- -cgit v1.2.1 - diff --git a/0002-CVE-2019-14889.patch b/0002-CVE-2019-14889.patch deleted file mode 100644 index c77de5c8ae037ba499c2494880976c34753c6d03..0000000000000000000000000000000000000000 --- a/0002-CVE-2019-14889.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 82c375b7c99141a5495e62060e0b7f9c97981e7e Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Fri, 25 Oct 2019 13:24:28 +0200 -Subject: CVE-2019-14889: scp: Log SCP warnings received from the server - -Fixes T181 - -Previously, warnings received from the server were ignored. With this -change the warning message sent by the server will be logged. - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider -(cherry picked from commit c75d417d06867fd792b788e6281334621c2cd335) ---- - src/scp.c | 75 ++++++++++----------------------------------------------------- - 1 file changed, 11 insertions(+), 64 deletions(-) - -diff --git a/src/scp.c b/src/scp.c -index 5de0e6ff..166f3d2f 100644 ---- a/src/scp.c -+++ b/src/scp.c -@@ -113,7 +113,6 @@ int ssh_scp_init(ssh_scp scp) - { - int rc; - char execbuffer[1024] = {0}; -- uint8_t code; - - if (scp == NULL) { - return SSH_ERROR; -@@ -157,19 +156,8 @@ int ssh_scp_init(ssh_scp scp) - } - - if (scp->mode == SSH_SCP_WRITE) { -- rc = ssh_channel_read(scp->channel, &code, 1, 0); -- if (rc <= 0) { -- ssh_set_error(scp->session, SSH_FATAL, -- "Error reading status code: %s", -- ssh_get_error(scp->session)); -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- -- if (code != 0) { -- ssh_set_error(scp->session, SSH_FATAL, -- "scp status code %ud not valid", code); -- scp->state = SSH_SCP_ERROR; -+ rc = ssh_scp_response(scp, NULL); -+ if (rc != 0) { - return SSH_ERROR; - } - } else { -@@ -277,7 +265,6 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode) - { - char buffer[1024] = {0}; - int rc; -- uint8_t code; - char *dir = NULL; - char *perms = NULL; - -@@ -303,19 +290,8 @@ int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode) - return SSH_ERROR; - } - -- rc = ssh_channel_read(scp->channel, &code, 1, 0); -- if (rc <= 0) { -- ssh_set_error(scp->session, SSH_FATAL, -- "Error reading status code: %s", -- ssh_get_error(scp->session)); -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- -- if (code != 0) { -- ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid", -- code); -- scp->state = SSH_SCP_ERROR; -+ rc = ssh_scp_response(scp, NULL); -+ if (rc != 0) { - return SSH_ERROR; - } - -@@ -334,7 +310,6 @@ int ssh_scp_leave_directory(ssh_scp scp) - { - char buffer[] = "E\n"; - int rc; -- uint8_t code; - - if (scp == NULL) { - return SSH_ERROR; -@@ -352,18 +327,8 @@ int ssh_scp_leave_directory(ssh_scp scp) - return SSH_ERROR; - } - -- rc = ssh_channel_read(scp->channel, &code, 1, 0); -- if (rc <= 0) { -- ssh_set_error(scp->session, SSH_FATAL, "Error reading status code: %s", -- ssh_get_error(scp->session)); -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- -- if (code != 0) { -- ssh_set_error(scp->session, SSH_FATAL, "scp status code %ud not valid", -- code); -- scp->state = SSH_SCP_ERROR; -+ rc = ssh_scp_response(scp, NULL); -+ if (rc != 0) { - return SSH_ERROR; - } - -@@ -395,7 +360,6 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, - int rc; - char *file = NULL; - char *perms = NULL; -- uint8_t code; - - if (scp == NULL) { - return SSH_ERROR; -@@ -422,19 +386,8 @@ int ssh_scp_push_file64(ssh_scp scp, const char *filename, uint64_t size, - return SSH_ERROR; - } - -- rc = ssh_channel_read(scp->channel, &code, 1, 0); -- if (rc <= 0) { -- ssh_set_error(scp->session, SSH_FATAL, -- "Error reading status code: %s", -- ssh_get_error(scp->session)); -- scp->state = SSH_SCP_ERROR; -- return SSH_ERROR; -- } -- -- if (code != 0) { -- ssh_set_error(scp->session, SSH_FATAL, -- "scp status code %ud not valid", code); -- scp->state = SSH_SCP_ERROR; -+ rc = ssh_scp_response(scp, NULL); -+ if (rc != 0) { - return SSH_ERROR; - } - -@@ -498,7 +451,7 @@ int ssh_scp_response(ssh_scp scp, char **response) - - if (code > 2) { - ssh_set_error(scp->session, SSH_FATAL, -- "SCP: invalid status code %ud received", code); -+ "SCP: invalid status code %u received", code); - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } -@@ -585,14 +538,8 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len) - * and handle */ - rc = ssh_channel_poll(scp->channel, 0); - if (rc > 0) { -- rc = ssh_channel_read(scp->channel, &code, 1, 0); -- if (rc == SSH_ERROR) { -- return SSH_ERROR; -- } -- -- if (code == 1 || code == 2) { -- ssh_set_error(scp->session, SSH_REQUEST_DENIED, -- "SCP: Error: status code %i received", code); -+ rc = ssh_scp_response(scp, NULL); -+ if (rc != 0) { - return SSH_ERROR; - } - } --- -cgit v1.2.1 - diff --git a/0003-CVE-2019-14889.patch b/0003-CVE-2019-14889.patch deleted file mode 100644 index f37f22d7607324438f339227d414415061b60031..0000000000000000000000000000000000000000 --- a/0003-CVE-2019-14889.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 2ba1dea5493fb2f5a5be2dd263ce46ccb5f8ec76 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Tue, 22 Oct 2019 16:08:24 +0200 -Subject: CVE-2019-14889: misc: Add function to quote file names - -The added function quote file names strings to be used in a shell. -Special cases are treated for the charactes '\'' and '!'. - -Fixes T181 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider -(cherry picked from commit c4ad1aba9860e02fe03ef3f58a047964e9e765fc) ---- - include/libssh/misc.h | 8 +++ - src/misc.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 192 insertions(+) - -diff --git a/include/libssh/misc.h b/include/libssh/misc.h -index bc50cff8..0531d4f3 100644 ---- a/include/libssh/misc.h -+++ b/include/libssh/misc.h -@@ -50,6 +50,12 @@ struct ssh_timestamp { - long useconds; - }; - -+enum ssh_quote_state_e { -+ NO_QUOTE, -+ SINGLE_QUOTE, -+ DOUBLE_QUOTE -+}; -+ - struct ssh_list *ssh_list_new(void); - void ssh_list_free(struct ssh_list *list); - struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list); -@@ -81,4 +87,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout); - - int ssh_match_group(const char *group, const char *object); - -+int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len); -+ - #endif /* MISC_H_ */ -diff --git a/src/misc.c b/src/misc.c -index 18c9745e..b042b46d 100644 ---- a/src/misc.c -+++ b/src/misc.c -@@ -1108,4 +1108,188 @@ char *strndup(const char *s, size_t n) - } - #endif /* ! HAVE_STRNDUP */ - -+/** -+ * @internal -+ * -+ * @brief Quote file name to be used on shell. -+ * -+ * Try to put the given file name between single quotes. There are special -+ * cases: -+ * -+ * - When the '\'' char is found in the file name, it is double quoted -+ * - example: -+ * input: a'b -+ * output: 'a'"'"'b' -+ * - When the '!' char is found in the file name, it is replaced by an unquoted -+ * verbatim char "\!" -+ * - example: -+ * input: a!b -+ * output 'a'\!'b' -+ * -+ * @param[in] file_name File name string to be quoted before used on shell -+ * @param[out] buf Buffer to receive the final quoted file name. Must -+ * have room for the final quoted string. The maximum -+ * output length would be (3 * strlen(file_name) + 1) -+ * since in the worst case each character would be -+ * replaced by 3 characters, plus the terminating '\0'. -+ * @param[in] buf_len The size of the provided output buffer -+ * -+ * @returns SSH_ERROR on error; length of the resulting string not counting the -+ * string terminator '\0' -+ * */ -+int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len) -+{ -+ const char *src = NULL; -+ char *dst = NULL; -+ size_t required_buf_len; -+ -+ enum ssh_quote_state_e state = NO_QUOTE; -+ -+ if (file_name == NULL || buf == NULL || buf_len == 0) { -+ SSH_LOG(SSH_LOG_WARNING, "Invalid parameter"); -+ return SSH_ERROR; -+ } -+ -+ /* Only allow file names smaller than 32kb. */ -+ if (strlen(file_name) > 32 * 1024) { -+ SSH_LOG(SSH_LOG_WARNING, "File name too long"); -+ return SSH_ERROR; -+ } -+ -+ /* Paranoia check */ -+ required_buf_len = (size_t)3 * strlen(file_name) + 1; -+ if (required_buf_len > buf_len) { -+ SSH_LOG(SSH_LOG_WARNING, "Buffer too small"); -+ return SSH_ERROR; -+ } -+ -+ src = file_name; -+ dst = buf; -+ -+ while ((*src != '\0')) { -+ switch (*src) { -+ -+ /* The '\'' char is double quoted */ -+ -+ case '\'': -+ switch (state) { -+ case NO_QUOTE: -+ /* Start a new double quoted string. The '\'' char will be -+ * copied to the beginning of it at the end of the loop. */ -+ *dst++ = '"'; -+ break; -+ case SINGLE_QUOTE: -+ /* Close the current single quoted string and start a new double -+ * quoted string. The '\'' char will be copied to the beginning -+ * of it at the end of the loop. */ -+ *dst++ = '\''; -+ *dst++ = '"'; -+ break; -+ case DOUBLE_QUOTE: -+ /* If already in the double quoted string, keep copying the -+ * sequence of chars. */ -+ break; -+ default: -+ /* Should never be reached */ -+ goto error; -+ } -+ -+ /* When the '\'' char is found, the resulting state will be -+ * DOUBLE_QUOTE in any case*/ -+ state = DOUBLE_QUOTE; -+ break; -+ -+ /* The '!' char is replaced by unquoted "\!" */ -+ -+ case '!': -+ switch (state) { -+ case NO_QUOTE: -+ /* The '!' char is interpreted in some shells (e.g. CSH) even -+ * when is quoted with single quotes. Replace it with unquoted -+ * "\!" which is correctly interpreted as the '!' character. */ -+ *dst++ = '\\'; -+ break; -+ case SINGLE_QUOTE: -+ /* Close the current quoted string and replace '!' for unquoted -+ * "\!" */ -+ *dst++ = '\''; -+ *dst++ = '\\'; -+ break; -+ case DOUBLE_QUOTE: -+ /* Close current quoted string and replace "!" for unquoted -+ * "\!" */ -+ *dst++ = '"'; -+ *dst++ = '\\'; -+ break; -+ default: -+ /* Should never be reached */ -+ goto error; -+ } -+ -+ /* When the '!' char is found, the resulting state will be NO_QUOTE -+ * in any case*/ -+ state = NO_QUOTE; -+ break; -+ -+ /* Ordinary chars are single quoted */ -+ -+ default: -+ switch (state) { -+ case NO_QUOTE: -+ /* Start a new single quoted string */ -+ *dst++ = '\''; -+ break; -+ case SINGLE_QUOTE: -+ /* If already in the single quoted string, keep copying the -+ * sequence of chars. */ -+ break; -+ case DOUBLE_QUOTE: -+ /* Close current double quoted string and start a new single -+ * quoted string. */ -+ *dst++ = '"'; -+ *dst++ = '\''; -+ break; -+ default: -+ /* Should never be reached */ -+ goto error; -+ } -+ -+ /* When an ordinary char is found, the resulting state will be -+ * SINGLE_QUOTE in any case*/ -+ state = SINGLE_QUOTE; -+ break; -+ } -+ -+ /* Copy the current char to output */ -+ *dst++ = *src++; -+ } -+ -+ /* Close the quoted string when necessary */ -+ -+ switch (state) { -+ case NO_QUOTE: -+ /* No open string */ -+ break; -+ case SINGLE_QUOTE: -+ /* Close current single quoted string */ -+ *dst++ = '\''; -+ break; -+ case DOUBLE_QUOTE: -+ /* Close current double quoted string */ -+ *dst++ = '"'; -+ break; -+ default: -+ /* Should never be reached */ -+ goto error; -+ } -+ -+ /* Put the string terminator */ -+ *dst = '\0'; -+ -+ return dst - buf; -+ -+error: -+ return SSH_ERROR; -+} -+ - /** @} */ --- -cgit v1.2.1 - diff --git a/0004-CVE-2019-14889.patch b/0004-CVE-2019-14889.patch deleted file mode 100644 index fbfe178e743884ef9c50b0c1326ecebd31c2a63b..0000000000000000000000000000000000000000 --- a/0004-CVE-2019-14889.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 391c78de9d0f7baec3a44d86a76f4e1324eb9529 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Fri, 6 Dec 2019 09:40:30 +0100 -Subject: CVE-2019-14889: scp: Don't allow file path longer than 32kb - -Signed-off-by: Andreas Schneider -Reviewed-by: Jakub Jelen -(cherry picked from commit 0b5ee397260b6e08dffa2c1ce515a153aaeda765) ---- - src/scp.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/scp.c b/src/scp.c -index 166f3d2f..4b00aa5f 100644 ---- a/src/scp.c -+++ b/src/scp.c -@@ -80,6 +80,12 @@ ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location) - goto error; - } - -+ if (strlen(location) > 32 * 1024) { -+ ssh_set_error(session, SSH_FATAL, -+ "Location path is too long"); -+ goto error; -+ } -+ - scp->location = strdup(location); - if (scp->location == NULL) { - ssh_set_error(session, SSH_FATAL, --- -cgit v1.2.1 - - diff --git a/0005-CVE-2019-14889.patch b/0005-CVE-2019-14889.patch deleted file mode 100644 index f1f29b7af3e2c5552df91f0b690e2452528d5f2d..0000000000000000000000000000000000000000 --- a/0005-CVE-2019-14889.patch +++ /dev/null @@ -1,128 +0,0 @@ -From b0edec4e8d01ad73b0d26ad4070d7e1a1e86dfc8 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Thu, 31 Oct 2019 18:10:27 +0100 -Subject: CVE-2019-14889: scp: Quote location to be used on shell - -Single quote file paths to be used on commands to be executed on remote -shell. - -Fixes T181 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider -(cherry picked from commit 3830c7ae6eec751b7618d3fc159cb5bb3c8806a6) ---- - src/scp.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 56 insertions(+), 6 deletions(-) - -diff --git a/src/scp.c b/src/scp.c -index 4b00aa5f..652551e3 100644 ---- a/src/scp.c -+++ b/src/scp.c -@@ -29,6 +29,7 @@ - - #include "libssh/priv.h" - #include "libssh/scp.h" -+#include "libssh/misc.h" - - /** - * @defgroup libssh_scp The SSH scp functions -@@ -119,6 +120,9 @@ int ssh_scp_init(ssh_scp scp) - { - int rc; - char execbuffer[1024] = {0}; -+ char *quoted_location = NULL; -+ size_t quoted_location_len = 0; -+ size_t scp_location_len; - - if (scp == NULL) { - return SSH_ERROR; -@@ -130,33 +134,79 @@ int ssh_scp_init(ssh_scp scp) - return SSH_ERROR; - } - -- SSH_LOG(SSH_LOG_PROTOCOL, -- "Initializing scp session %s %son location '%s'", -+ if (scp->location == NULL) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Invalid scp context: location is NULL"); -+ return SSH_ERROR; -+ } -+ -+ SSH_LOG(SSH_LOG_PROTOCOL, "Initializing scp session %s %son location '%s'", - scp->mode == SSH_SCP_WRITE?"write":"read", -- scp->recursive?"recursive ":"", -+ scp->recursive ? "recursive " : "", - scp->location); - - scp->channel = ssh_channel_new(scp->session); - if (scp->channel == NULL) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Channel creation failed for scp"); - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } - - rc = ssh_channel_open_session(scp->channel); - if (rc == SSH_ERROR) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Failed to open channel for scp"); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ /* In the worst case, each character would be replaced by 3 plus the string -+ * terminator '\0' */ -+ scp_location_len = strlen(scp->location); -+ quoted_location_len = ((size_t)3 * scp_location_len) + 1; -+ /* Paranoia check */ -+ if (quoted_location_len < scp_location_len) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Buffer overflow detected"); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ quoted_location = (char *)calloc(1, quoted_location_len); -+ if (quoted_location == NULL) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Failed to allocate memory for quoted location"); -+ scp->state = SSH_SCP_ERROR; -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_quote_file_name(scp->location, quoted_location, -+ quoted_location_len); -+ if (rc <= 0) { -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Failed to single quote command location"); -+ SAFE_FREE(quoted_location); - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } - - if (scp->mode == SSH_SCP_WRITE) { - snprintf(execbuffer, sizeof(execbuffer), "scp -t %s %s", -- scp->recursive ? "-r":"", scp->location); -+ scp->recursive ? "-r" : "", quoted_location); - } else { - snprintf(execbuffer, sizeof(execbuffer), "scp -f %s %s", -- scp->recursive ? "-r":"", scp->location); -+ scp->recursive ? "-r" : "", quoted_location); - } - -- if (ssh_channel_request_exec(scp->channel, execbuffer) == SSH_ERROR) { -+ SAFE_FREE(quoted_location); -+ -+ SSH_LOG(SSH_LOG_DEBUG, "Executing command: %s", execbuffer); -+ -+ rc = ssh_channel_request_exec(scp->channel, execbuffer); -+ if (rc == SSH_ERROR){ -+ ssh_set_error(scp->session, SSH_FATAL, -+ "Failed executing command: %s", execbuffer); - scp->state = SSH_SCP_ERROR; - return SSH_ERROR; - } --- -cgit v1.2.1 - diff --git a/CVE-2020-1730.patch b/CVE-2020-1730.patch deleted file mode 100644 index 4e812143c52415995b8bf6c8808d2ab169a527a0..0000000000000000000000000000000000000000 --- a/CVE-2020-1730.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 26a8b6535159e3f7fb4a6204373b195f09e3bc20 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 11 Feb 2020 11:52:33 +0100 -Subject: [PATCH] CVE-2020-1730: Fix a possible segfault when zeroing AES-CTR - key - -Fixes T213 - -Signed-off-by: Andreas Schneider -Reviewed-by: Anderson Toshiyuki Sasaki ---- - src/libcrypto.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/libcrypto.c b/src/libcrypto.c -index b24a18f..2d692cd 100644 ---- a/src/libcrypto.c -+++ b/src/libcrypto.c -@@ -638,8 +638,12 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou - } - - static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){ -- explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key)); -- SAFE_FREE(cipher->aes_key); -+ if (cipher != NULL) { -+ if (cipher->aes_key != NULL) { -+ explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key)); -+ } -+ SAFE_FREE(cipher->aes_key); -+ } - } - - #endif /* HAVE_OPENSSL_EVP_AES_CTR */ --- -1.8.3.1 - diff --git a/libssh-0.8.3-fix-covscan-errors.patch b/libssh-0.8.3-fix-covscan-errors.patch deleted file mode 100644 index 6110c829d089a978f0d7f955d9768373b119fef3..0000000000000000000000000000000000000000 --- a/libssh-0.8.3-fix-covscan-errors.patch +++ /dev/null @@ -1,2065 +0,0 @@ -diff --git a/examples/libssh_scp.c b/examples/libssh_scp.c -index 46199f47..ff38b830 100644 ---- a/examples/libssh_scp.c -+++ b/examples/libssh_scp.c -@@ -25,148 +25,230 @@ program. - static char **sources; - static int nsources; - static char *destination; --static int verbosity=0; -+static int verbosity = 0; - - struct location { -- int is_ssh; -- char *user; -- char *host; -- char *path; -- ssh_session session; -- ssh_scp scp; -- FILE *file; -+ int is_ssh; -+ char *user; -+ char *host; -+ char *path; -+ ssh_session session; -+ ssh_scp scp; -+ FILE *file; - }; - - enum { -- READ, -- WRITE -+ READ, -+ WRITE - }; - --static void usage(const char *argv0){ -- fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n" -- " [[user@]host2:]destination\n" -- "sample scp client - libssh-%s\n", --// "Options :\n", --// " -r : use RSA to verify host public key\n", -- argv0, -- ssh_version(0)); -- exit(0); -+static void usage(const char *argv0) { -+ fprintf(stderr, "Usage : %s [options] [[user@]host1:]file1 ... \n" -+ " [[user@]host2:]destination\n" -+ "sample scp client - libssh-%s\n", -+ // "Options :\n", -+ // " -r : use RSA to verify host public key\n", -+ argv0, -+ ssh_version(0)); -+ exit(0); - } - --static int opts(int argc, char **argv){ -- int i; -- while((i=getopt(argc,argv,"v"))!=-1){ -- switch(i){ -- case 'v': -- verbosity++; -- break; -- default: -- fprintf(stderr,"unknown option %c\n",optopt); -+static int opts(int argc, char **argv) { -+ int i; -+ -+ while((i = getopt(argc, argv, "v")) != -1) { -+ switch(i) { -+ case 'v': -+ verbosity++; -+ break; -+ default: -+ fprintf(stderr, "unknown option %c\n", optopt); -+ usage(argv[0]); -+ return -1; -+ } -+ } -+ -+ nsources = argc - optind - 1; -+ if (nsources < 1) { - usage(argv[0]); - return -1; - } -- } -- nsources=argc-optind-1; -- if(nsources < 1){ -- usage(argv[0]); -- return -1; -- } -- sources=malloc((nsources + 1) * sizeof(char *)); -- if(sources == NULL) -- return -1; -- for(i=0;ihost=location->user=NULL; -- ptr=strchr(loc,':'); -- if(ptr != NULL){ -- location->is_ssh=1; -- location->path=strdup(ptr+1); -- *ptr='\0'; -- ptr=strchr(loc,'@'); -- if(ptr != NULL){ -- location->host=strdup(ptr+1); -- *ptr='\0'; -- location->user=strdup(loc); -- } else { -- location->host=strdup(loc); -+ sources = malloc((nsources + 1) * sizeof(char *)); -+ if (sources == NULL) { -+ return -1; - } -- } else { -- location->is_ssh=0; -- location->path=strdup(loc); -- } -- return location; --} - --static int open_location(struct location *loc, int flag){ -- if(loc->is_ssh && flag==WRITE){ -- loc->session=connect_ssh(loc->host,loc->user,verbosity); -- if(!loc->session){ -- fprintf(stderr,"Couldn't connect to %s\n",loc->host); -- return -1; -+ for(i = 0; i < nsources; ++i) { -+ sources[i] = argv[optind]; -+ optind++; - } -- loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path); -- if(!loc->scp){ -- fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); -- return -1; -+ -+ sources[i] = NULL; -+ destination = argv[optind]; -+ return 0; -+} -+ -+static void location_free(struct location *loc) -+{ -+ if (loc) { -+ if (loc->path) { -+ free(loc->path); -+ } -+ loc->path = NULL; -+ if (loc->is_ssh) { -+ if (loc->host) { -+ free(loc->host); -+ } -+ loc->host = NULL; -+ if (loc->user) { -+ free(loc->user); -+ } -+ loc->user = NULL; -+ if (loc->host) { -+ free(loc->host); -+ } -+ loc->host = NULL; -+ } -+ free(loc); - } -- if(ssh_scp_init(loc->scp)==SSH_ERROR){ -- fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); -- ssh_scp_free(loc->scp); -- loc->scp = NULL; -- return -1; -+} -+ -+static struct location *parse_location(char *loc) { -+ struct location *location; -+ char *ptr; -+ -+ location = malloc(sizeof(struct location)); -+ if (location == NULL) { -+ return NULL; - } -- return 0; -- } else if(loc->is_ssh && flag==READ){ -- loc->session=connect_ssh(loc->host, loc->user,verbosity); -- if(!loc->session){ -- fprintf(stderr,"Couldn't connect to %s\n",loc->host); -- return -1; -+ memset(location, 0, sizeof(struct location)); -+ -+ location->host = location->user = NULL; -+ ptr = strchr(loc, ':'); -+ -+ if (ptr != NULL) { -+ location->is_ssh = 1; -+ location->path = strdup(ptr+1); -+ *ptr = '\0'; -+ ptr = strchr(loc, '@'); -+ -+ if (ptr != NULL) { -+ location->host = strdup(ptr+1); -+ *ptr = '\0'; -+ location->user = strdup(loc); -+ } else { -+ location->host = strdup(loc); -+ } -+ } else { -+ location->is_ssh = 0; -+ location->path = strdup(loc); - } -- loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path); -- if(!loc->scp){ -- fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); -- return -1; -+ return location; -+} -+ -+static void close_location(struct location *loc) { -+ int rc; -+ -+ if (loc) { -+ if (loc->is_ssh) { -+ if (loc->scp) { -+ rc = ssh_scp_close(loc->scp); -+ if (rc == SSH_ERROR) { -+ fprintf(stderr, -+ "Error closing scp: %s\n", -+ ssh_get_error(loc->session)); -+ } -+ ssh_scp_free(loc->scp); -+ loc->scp = NULL; -+ } -+ if (loc->session) { -+ ssh_disconnect(loc->session); -+ ssh_free(loc->session); -+ loc->session = NULL; -+ } -+ } else { -+ if (loc->file) { -+ fclose(loc->file); -+ loc->file = NULL; -+ } -+ } - } -- if(ssh_scp_init(loc->scp)==SSH_ERROR){ -- fprintf(stderr,"error : %s\n",ssh_get_error(loc->session)); -- ssh_scp_free(loc->scp); -- loc->scp = NULL; -- return -1; -+} -+ -+static int open_location(struct location *loc, int flag) { -+ if (loc->is_ssh && flag == WRITE) { -+ loc->session = connect_ssh(loc->host, loc->user, verbosity); -+ if (!loc->session) { -+ fprintf(stderr, "Couldn't connect to %s\n", loc->host); -+ return -1; -+ } -+ -+ loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path); -+ if (!loc->scp) { -+ fprintf(stderr, "error : %s\n", ssh_get_error(loc->session)); -+ ssh_disconnect(loc->session); -+ ssh_free(loc->session); -+ loc->session = NULL; -+ return -1; -+ } -+ -+ if (ssh_scp_init(loc->scp) == SSH_ERROR) { -+ fprintf(stderr, "error : %s\n", ssh_get_error(loc->session)); -+ ssh_scp_free(loc->scp); -+ loc->scp = NULL; -+ ssh_disconnect(loc->session); -+ ssh_free(loc->session); -+ loc->session = NULL; -+ return -1; -+ } -+ return 0; -+ } else if (loc->is_ssh && flag == READ) { -+ loc->session = connect_ssh(loc->host, loc->user, verbosity); -+ if (!loc->session) { -+ fprintf(stderr, "Couldn't connect to %s\n", loc->host); -+ return -1; -+ } -+ -+ loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path); -+ if (!loc->scp) { -+ fprintf(stderr, "error : %s\n", ssh_get_error(loc->session)); -+ ssh_disconnect(loc->session); -+ ssh_free(loc->session); -+ loc->session = NULL; -+ return -1; -+ } -+ -+ if (ssh_scp_init(loc->scp) == SSH_ERROR) { -+ fprintf(stderr, "error : %s\n", ssh_get_error(loc->session)); -+ ssh_scp_free(loc->scp); -+ loc->scp = NULL; -+ ssh_disconnect(loc->session); -+ ssh_free(loc->session); -+ loc->session = NULL; -+ return -1; -+ } -+ return 0; -+ } else { -+ loc->file = fopen(loc->path, flag == READ ? "r":"w"); -+ if (!loc->file) { -+ if (errno == EISDIR) { -+ if (chdir(loc->path)) { -+ fprintf(stderr, -+ "Error changing directory to %s: %s\n", -+ loc->path, strerror(errno)); -+ return -1; -+ } -+ return 0; -+ } -+ fprintf(stderr, -+ "Error opening %s: %s\n", -+ loc->path, strerror(errno)); -+ return -1; -+ } -+ return 0; - } -- return 0; -- } else { -- loc->file=fopen(loc->path,flag==READ ? "r":"w"); -- if(!loc->file){ -- if(errno==EISDIR){ -- if(chdir(loc->path)){ -- fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno)); -- return -1; -- } -- return 0; -- } -- fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno)); -- return -1; -- } -- return 0; -- } -- return -1; -+ return -1; - } - - /** @brief copies files from source location to destination -@@ -174,155 +256,197 @@ static int open_location(struct location *loc, int flag){ - * @param dest destination location - * @param recursive Copy also directories - */ --static int do_copy(struct location *src, struct location *dest, int recursive){ -- int size; -- socket_t fd; -- struct stat s; -- int w,r; -- char buffer[16384]; -- int total=0; -- int mode; -- char *filename = NULL; -- /* recursive mode doesn't work yet */ -- (void)recursive; -- /* Get the file name and size*/ -- if(!src->is_ssh){ -- fd = fileno(src->file); -- if (fd < 0) { -- fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno)); -- return -1; -+static int do_copy(struct location *src, struct location *dest, int recursive) { -+ int size; -+ socket_t fd; -+ struct stat s; -+ int w, r; -+ char buffer[16384]; -+ int total = 0; -+ int mode; -+ char *filename = NULL; -+ /* recursive mode doesn't work yet */ -+ (void)recursive; -+ /* Get the file name and size*/ -+ if (!src->is_ssh) { -+ fd = fileno(src->file); -+ if (fd < 0) { -+ fprintf(stderr, -+ "Invalid file pointer, error: %s\n", -+ strerror(errno)); -+ return -1; -+ } -+ r = fstat(fd, &s); -+ if (r < 0) { -+ return -1; -+ } -+ size = s.st_size; -+ mode = s.st_mode & ~S_IFMT; -+ filename = ssh_basename(src->path); -+ } else { -+ size = 0; -+ do { -+ r = ssh_scp_pull_request(src->scp); -+ if (r == SSH_SCP_REQUEST_NEWDIR) { -+ ssh_scp_deny_request(src->scp, "Not in recursive mode"); -+ continue; -+ } -+ if (r == SSH_SCP_REQUEST_NEWFILE) { -+ size = ssh_scp_request_get_size(src->scp); -+ filename = strdup(ssh_scp_request_get_filename(src->scp)); -+ mode = ssh_scp_request_get_permissions(src->scp); -+ //ssh_scp_accept_request(src->scp); -+ break; -+ } -+ if (r == SSH_ERROR) { -+ fprintf(stderr, -+ "Error: %s\n", -+ ssh_get_error(src->session)); -+ ssh_string_free_char(filename); -+ return -1; -+ } -+ } while(r != SSH_SCP_REQUEST_NEWFILE); - } -- r = fstat(fd, &s); -- if (r < 0) { -- return -1; -+ -+ if (dest->is_ssh) { -+ r = ssh_scp_push_file(dest->scp, src->path, size, mode); -+ // snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path); -+ if (r == SSH_ERROR) { -+ fprintf(stderr, -+ "error: %s\n", -+ ssh_get_error(dest->session)); -+ ssh_string_free_char(filename); -+ ssh_scp_free(dest->scp); -+ dest->scp = NULL; -+ return -1; -+ } -+ } else { -+ if (!dest->file) { -+ dest->file = fopen(filename, "w"); -+ if (!dest->file) { -+ fprintf(stderr, -+ "Cannot open %s for writing: %s\n", -+ filename, strerror(errno)); -+ if (src->is_ssh) { -+ ssh_scp_deny_request(src->scp, "Cannot open local file"); -+ } -+ ssh_string_free_char(filename); -+ return -1; -+ } -+ } -+ if (src->is_ssh) { -+ ssh_scp_accept_request(src->scp); -+ } - } -- size=s.st_size; -- mode = s.st_mode & ~S_IFMT; -- filename=ssh_basename(src->path); -- } else { -- size=0; -+ - do { -- r=ssh_scp_pull_request(src->scp); -- if(r==SSH_SCP_REQUEST_NEWDIR){ -- ssh_scp_deny_request(src->scp,"Not in recursive mode"); -- continue; -- } -- if(r==SSH_SCP_REQUEST_NEWFILE){ -- size=ssh_scp_request_get_size(src->scp); -- filename=strdup(ssh_scp_request_get_filename(src->scp)); -- mode=ssh_scp_request_get_permissions(src->scp); -- //ssh_scp_accept_request(src->scp); -- break; -- } -- if(r==SSH_ERROR){ -- fprintf(stderr,"Error: %s\n",ssh_get_error(src->session)); -+ if (src->is_ssh) { -+ r = ssh_scp_read(src->scp, buffer, sizeof(buffer)); -+ if (r == SSH_ERROR) { -+ fprintf(stderr, -+ "Error reading scp: %s\n", -+ ssh_get_error(src->session)); -+ ssh_string_free_char(filename); -+ return -1; -+ } -+ -+ if (r == 0) { -+ break; -+ } -+ } else { -+ r = fread(buffer, 1, sizeof(buffer), src->file); -+ if (r == 0) { -+ break; -+ } -+ -+ if (r < 0) { -+ fprintf(stderr, -+ "Error reading file: %s\n", -+ strerror(errno)); -+ ssh_string_free_char(filename); -+ return -1; -+ } -+ } -+ -+ if (dest->is_ssh) { -+ w = ssh_scp_write(dest->scp, buffer, r); -+ if (w == SSH_ERROR) { -+ fprintf(stderr, -+ "Error writing in scp: %s\n", -+ ssh_get_error(dest->session)); -+ ssh_scp_free(dest->scp); -+ dest->scp = NULL; -+ ssh_string_free_char(filename); -+ return -1; -+ } -+ } else { -+ w = fwrite(buffer, r, 1, dest->file); -+ if (w <= 0) { -+ fprintf(stderr, -+ "Error writing in local file: %s\n", -+ strerror(errno)); - ssh_string_free_char(filename); -- return -1; -- } -- } while(r != SSH_SCP_REQUEST_NEWFILE); -- } -- -- if(dest->is_ssh){ -- r=ssh_scp_push_file(dest->scp,src->path, size, mode); -- // snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path); -- if(r==SSH_ERROR){ -- fprintf(stderr,"error: %s\n",ssh_get_error(dest->session)); -- ssh_string_free_char(filename); -- ssh_scp_free(dest->scp); -- dest->scp = NULL; -- return -1; -- } -- } else { -- if(!dest->file){ -- dest->file=fopen(filename,"w"); -- if(!dest->file){ -- fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno)); -- if(src->is_ssh) -- ssh_scp_deny_request(src->scp,"Cannot open local file"); -- ssh_string_free_char(filename); -- return -1; -- } -- } -- if(src->is_ssh){ -- ssh_scp_accept_request(src->scp); -- } -- } -- do { -- if(src->is_ssh){ -- r=ssh_scp_read(src->scp,buffer,sizeof(buffer)); -- if(r==SSH_ERROR){ -- fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session)); -- ssh_string_free_char(filename); -- return -1; -- } -- if(r==0) -- break; -- } else { -- r=fread(buffer,1,sizeof(buffer),src->file); -- if(r==0) -- break; -- if(r<0){ -- fprintf(stderr,"Error reading file: %s\n",strerror(errno)); -- ssh_string_free_char(filename); -- return -1; -- } -- } -- if(dest->is_ssh){ -- w=ssh_scp_write(dest->scp,buffer,r); -- if(w == SSH_ERROR){ -- fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session)); -- ssh_scp_free(dest->scp); -- dest->scp=NULL; -- ssh_string_free_char(filename); -- return -1; -- } -- } else { -- w=fwrite(buffer,r,1,dest->file); -- if(w<=0){ -- fprintf(stderr,"Error writing in local file: %s\n",strerror(errno)); -- ssh_string_free_char(filename); -- return -1; -- } -- } -- total+=r; -- -- } while(total < size); -- ssh_string_free_char(filename); -- printf("wrote %d bytes\n",total); -- return 0; -+ return -1; -+ } -+ } -+ total += r; -+ -+ } while(total < size); -+ -+ ssh_string_free_char(filename); -+ printf("wrote %d bytes\n", total); -+ return 0; - } - --int main(int argc, char **argv){ -- struct location *dest, *src; -- int i; -- int r; -- if(opts(argc,argv)<0) -- return EXIT_FAILURE; -- dest=parse_location(destination); -- if(open_location(dest,WRITE)<0) -- return EXIT_FAILURE; -- for(i=0;iis_ssh && dest->scp != NULL) { -- r=ssh_scp_close(dest->scp); -- if(r == SSH_ERROR){ -- fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session)); -- ssh_scp_free(dest->scp); -- dest->scp=NULL; -- return -1; -- } -- } else { -- fclose(dest->file); -- dest->file=NULL; -- } -- ssh_disconnect(dest->session); -- ssh_finalize(); -- return 0; -+ -+ for (i = 0; i < nsources; ++i) { -+ src = parse_location(sources[i]); -+ if (src == NULL) { -+ r = EXIT_FAILURE; -+ goto close_dest; -+ } -+ -+ if (open_location(src, READ) < 0) { -+ location_free(src); -+ r = EXIT_FAILURE; -+ goto close_dest; -+ } -+ -+ if (do_copy(src, dest, 0) < 0) { -+ close_location(src); -+ location_free(src); -+ break; -+ } -+ -+ close_location(src); -+ location_free(src); -+ } -+ -+ r = 0; -+ -+close_dest: -+ close_location(dest); -+ location_free(dest); -+end: -+ return r; - } -diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h -index a83bd8a2..a5d046f0 100644 ---- a/include/libssh/libssh.h -+++ b/include/libssh/libssh.h -@@ -630,6 +630,8 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len, - int echo, int verify, void *userdata); - - 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) - LIBSSH_API void ssh_key_free (ssh_key key); - LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key); - LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type); -diff --git a/src/messages.c b/src/messages.c -index 9ddfe15c..8733875c 100644 ---- a/src/messages.c -+++ b/src/messages.c -@@ -430,6 +430,13 @@ void ssh_message_queue(ssh_session session, ssh_message message){ - } - if (session->ssh_message_list != NULL) { - ssh_list_append(session->ssh_message_list, message); -+ } else { -+ /* If the message list couldn't be allocated, the message can't be -+ * enqueued */ -+ ssh_message_reply_default(message); -+ ssh_set_error_oom(session); -+ ssh_message_free(message); -+ return; - } - } - } -diff --git a/tests/client/torture_auth.c b/tests/client/torture_auth.c -index df7f2714..5f4a4ed8 100644 ---- a/tests/client/torture_auth.c -+++ b/tests/client/torture_auth.c -@@ -534,8 +534,8 @@ static void torture_auth_cert(void **state) { - rc = ssh_userauth_publickey(session, NULL, privkey); - assert_int_equal(rc, SSH_AUTH_SUCCESS); - -- ssh_key_free(privkey); -- ssh_key_free(cert); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(cert); - } - - static void torture_auth_agent_cert(void **state) { -diff --git a/tests/unittests/torture_buffer.c b/tests/unittests/torture_buffer.c -index 4d29a2a5..f5cb8f65 100644 ---- a/tests/unittests/torture_buffer.c -+++ b/tests/unittests/torture_buffer.c -@@ -22,7 +22,7 @@ static int setup(void **state) { - } - - static int teardown(void **state) { -- ssh_buffer_free(*state); -+ SSH_BUFFER_FREE(*state); - - return 0; - } -@@ -125,9 +125,9 @@ static void torture_ssh_buffer_get_ssh_string(void **state) { - for(l=0;lopts.wanted_methods[SSH_KEX], KEXALGORITHMS); - -@@ -223,14 +223,14 @@ static void torture_config_glob(void **state) { - assert_non_null(v); - - assert_string_equal(v, PROXYCMD); -- ssh_string_free_char(v); -+ SSH_STRING_FREE_CHAR(v); - - ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v); - assert_true(ret == 0); - assert_non_null(v); - - assert_string_equal(v, ID_FILE); -- ssh_string_free_char(v); -+ SSH_STRING_FREE_CHAR(v); - #endif /* HAVE_GLOB */ - } - -diff --git a/tests/unittests/torture_hashes.c b/tests/unittests/torture_hashes.c -index 104aa7c9..59e23d28 100644 ---- a/tests/unittests/torture_hashes.c -+++ b/tests/unittests/torture_hashes.c -@@ -41,88 +41,91 @@ static int setup_rsa_key(void **state) - - static int teardown(void **state) - { -- ssh_key_free(*state); -+ SSH_KEY_FREE(*state); - return 0; - } - - static void torture_md5_hash(void **state) - { - ssh_key pubkey = *state; -- unsigned char *hash = NULL; -+ char *hash = NULL; - char *hexa = NULL; - size_t hlen; - int rc = 0; - -- rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); -+ rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, -+ (unsigned char **)&hash, &hlen); - assert_true(rc == 0); - -- hexa = ssh_get_hexa(hash, hlen); -- ssh_string_free_char((char *)hash); -+ hexa = ssh_get_hexa((unsigned char *)hash, hlen); -+ SSH_STRING_FREE_CHAR(hash); - assert_string_equal(hexa, - "50:15:a0:9b:92:bf:33:1c:01:c5:8c:fe:18:fa:ce:78"); - -- ssh_string_free_char(hexa); -+ SSH_STRING_FREE_CHAR(hexa); - } - - static void torture_sha1_hash(void **state) - { - ssh_key pubkey = *state; -- unsigned char *hash = NULL; -+ char *hash = NULL; - char *sha1 = NULL; - int rc = 0; - size_t hlen; - -- rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen); -+ rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1, -+ (unsigned char **)&hash, &hlen); - assert_true(rc == 0); - -- sha1 = ssh_get_b64_unpadded(hash, hlen); -- ssh_string_free_char((char *)hash); -+ sha1 = ssh_get_b64_unpadded((unsigned char *)hash, hlen); -+ SSH_STRING_FREE_CHAR(hash); - assert_string_equal(sha1, "6wP+houujQmxLBiFugTcoeoODCM"); - -- ssh_string_free_char(sha1); -+ SSH_STRING_FREE_CHAR(sha1); - } - - static void torture_sha256_hash(void **state) - { - ssh_key pubkey = *state; -- unsigned char *hash = NULL; -+ char *hash = NULL; - char *sha256 = NULL; - int rc = 0; - size_t hlen; - -- rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen); -+ rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256, -+ (unsigned char **)&hash, &hlen); - assert_true(rc == 0); - -- sha256 = ssh_get_b64_unpadded(hash, hlen); -- ssh_string_free_char((char *)hash); -+ sha256 = ssh_get_b64_unpadded((unsigned char *)hash, hlen); -+ SSH_STRING_FREE_CHAR(hash); - assert_string_equal(sha256, "jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII"); - -- ssh_string_free_char(sha256); -+ SSH_STRING_FREE_CHAR(sha256); - - } - - static void torture_sha256_fingerprint(void **state) - { - ssh_key pubkey = *state; -- unsigned char *hash = NULL; -+ char *hash = NULL; - char *sha256 = NULL; - int rc = 0; - size_t hlen; - - rc = ssh_get_publickey_hash(pubkey, - SSH_PUBLICKEY_HASH_SHA256, -- &hash, -+ (unsigned char **)&hash, - &hlen); - assert_true(rc == 0); - - sha256 = ssh_get_fingerprint_hash(SSH_PUBLICKEY_HASH_SHA256, -- hash, -+ (unsigned char *)hash, - hlen); -- ssh_string_free_char(discard_const(hash)); -+ SSH_STRING_FREE_CHAR(hash); - assert_string_equal(sha256, - "SHA256:jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII"); - -- ssh_string_free_char(sha256); -+ SSH_STRING_FREE_CHAR(sha256); - } - - int torture_run_tests(void) { -diff --git a/tests/unittests/torture_keyfiles.c b/tests/unittests/torture_keyfiles.c -index de924f00..59a4f5ee 100644 ---- a/tests/unittests/torture_keyfiles.c -+++ b/tests/unittests/torture_keyfiles.c -@@ -111,7 +111,7 @@ static void torture_pubkey_from_file(void **state) { - - assert_true(rc == 0); - -- ssh_string_free(pubkey); -+ SSH_STRING_FREE(pubkey); - - /* test if it returns 1 if pubkey doesn't exist */ - unlink(LIBSSH_RSA_TESTKEY ".pub"); -@@ -119,11 +119,17 @@ static void torture_pubkey_from_file(void **state) { - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); - assert_true(rc == 1); - -+ /* This free is unnecessary, but the static analyser does not know */ -+ SSH_STRING_FREE(pubkey); -+ - /* test if it returns -1 if privkey doesn't exist */ - unlink(LIBSSH_RSA_TESTKEY); - - rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type); - assert_true(rc == -1); -+ -+ /* This free is unnecessary, but the static analyser does not know */ -+ SSH_STRING_FREE(pubkey); - } - - static int torture_read_one_line(const char *filename, char *buffer, size_t len) { -@@ -210,8 +216,8 @@ static void torture_pubkey_generate_from_privkey(void **state) { - - assert_string_equal(pubkey_line_orig, pubkey_line_new); - -- ssh_string_free(pubkey_orig); -- ssh_string_free(pubkey_new); -+ SSH_STRING_FREE(pubkey_orig); -+ SSH_STRING_FREE(pubkey_new); - } - - /** -diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c -index d9cd6e2a..7addce76 100644 ---- a/tests/unittests/torture_options.c -+++ b/tests/unittests/torture_options.c -@@ -560,7 +560,7 @@ static void torture_bind_options_import_key(void **state) - /* set invalid key */ - rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key); - assert_int_equal(rc, -1); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - - /* set rsa key */ - base64_key = torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0); -diff --git a/tests/unittests/torture_pki_dsa.c b/tests/unittests/torture_pki_dsa.c -index e8d03904..41ab9063 100644 ---- a/tests/unittests/torture_pki_dsa.c -+++ b/tests/unittests/torture_pki_dsa.c -@@ -82,7 +82,7 @@ static void torture_pki_dsa_import_pubkey_file(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state) -@@ -97,7 +97,7 @@ static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_dsa_import_privkey_base64(void **state) -@@ -115,7 +115,7 @@ static void torture_pki_dsa_import_privkey_base64(void **state) - &key); - assert_true(rc == 0); - -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - #ifdef HAVE_LIBCRYPTO -@@ -154,8 +154,8 @@ static void torture_pki_dsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - - /* Test with passphrase */ - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY_PASSPHRASE, -@@ -192,8 +192,8 @@ static void torture_pki_dsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - } - #endif - -@@ -215,8 +215,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), -@@ -247,8 +246,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1), -@@ -259,7 +257,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state) - assert_true(rc == -1); - - /* This free in unnecessary, but the static analyser does not know */ -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - - #ifndef HAVE_LIBCRYPTO - /* test if it returns -1 if passphrase is NULL */ -@@ -272,7 +270,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state) - assert_true(rc == -1); - - /* This free in unnecessary, but the static analyser does not know */ -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - #endif /* HAVE_LIBCRYPTO */ - } - -@@ -299,8 +297,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(keystring, -@@ -328,8 +325,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(keystring, -@@ -339,6 +335,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state) - &key); - assert_true(rc == -1); - -+ /* This free is unnecessary, but the static analyser does not know */ -+ SSH_KEY_FREE(key); -+ - /* test if it returns -1 if passphrase is NULL */ - rc = ssh_pki_import_privkey_base64(keystring, - NULL, -@@ -346,6 +345,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -+ -+ /* This free is unnecessary, but the static analyser does not know */ -+ SSH_KEY_FREE(key); - } - - -@@ -371,8 +373,8 @@ static void torture_pki_dsa_publickey_from_privatekey(void **state) - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - -- ssh_key_free(key); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_dsa_import_cert_file(void **state) -@@ -392,7 +394,7 @@ static void torture_pki_dsa_import_cert_file(void **state) - rc = ssh_key_is_public(cert); - assert_true(rc == 1); - -- ssh_key_free(cert); -+ SSH_KEY_FREE(cert); - } - - static void torture_pki_dsa_publickey_base64(void **state) -@@ -443,7 +445,7 @@ static void torture_pki_dsa_publickey_base64(void **state) - - free(b64_key); - free(key_buf); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_dsa_generate_pubkey_from_privkey(void **state) -@@ -482,8 +484,8 @@ static void torture_pki_dsa_generate_pubkey_from_privkey(void **state) - pubkey_generated, - len); - -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_dsa_duplicate_key(void **state) -@@ -503,7 +505,7 @@ static void torture_pki_dsa_duplicate_key(void **state) - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY, - NULL, -@@ -530,11 +532,11 @@ static void torture_pki_dsa_duplicate_key(void **state) - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(pubkey); -- ssh_key_free(privkey); -- ssh_key_free(privkey_dup); -- ssh_string_free_char(b64_key); -- ssh_string_free_char(b64_key_gen); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(privkey_dup); -+ SSH_STRING_FREE_CHAR(b64_key); -+ SSH_STRING_FREE_CHAR(b64_key_gen); - } - - static void torture_pki_dsa_generate_key(void **state) -@@ -553,8 +555,7 @@ static void torture_pki_dsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,DSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 2048, &key); - assert_true(rc == SSH_OK); -@@ -564,8 +565,7 @@ static void torture_pki_dsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,DSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 3072, &key); - assert_true(rc == SSH_OK); -@@ -575,8 +575,7 @@ static void torture_pki_dsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,DSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - ssh_free(session); - } -diff --git a/tests/unittests/torture_pki_ecdsa.c b/tests/unittests/torture_pki_ecdsa.c -index 497c7379..7ef354f7 100644 ---- a/tests/unittests/torture_pki_ecdsa.c -+++ b/tests/unittests/torture_pki_ecdsa.c -@@ -121,7 +121,7 @@ static void torture_pki_ecdsa_import_pubkey_file(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state) -@@ -136,7 +136,7 @@ static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ecdsa_import_privkey_base64(void **state) -@@ -158,7 +158,7 @@ static void torture_pki_ecdsa_import_privkey_base64(void **state) - assert_true(rc == 1); - - free(key_str); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ecdsa_publickey_from_privatekey(void **state) -@@ -181,8 +181,8 @@ static void torture_pki_ecdsa_publickey_from_privatekey(void **state) - assert_true(rc == SSH_OK); - - free(key_str); -- ssh_key_free(key); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ecdsa_publickey_base64(void **state) -@@ -219,7 +219,7 @@ static void torture_pki_ecdsa_publickey_base64(void **state) - - free(b64_key); - free(key_buf); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state) -@@ -261,8 +261,8 @@ static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state) - len = torture_pubkey_len(pubkey_original); - assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0); - -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ecdsa_duplicate_key(void **state) -@@ -281,7 +281,7 @@ static void torture_pki_ecdsa_duplicate_key(void **state) - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, - NULL, -@@ -307,11 +307,11 @@ static void torture_pki_ecdsa_duplicate_key(void **state) - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(pubkey); -- ssh_key_free(privkey); -- ssh_key_free(privkey_dup); -- ssh_string_free_char(b64_key); -- ssh_string_free_char(b64_key_gen); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(privkey_dup); -+ SSH_STRING_FREE_CHAR(b64_key); -+ SSH_STRING_FREE_CHAR(b64_key_gen); - } - - /* Test case for bug #147: Private ECDSA key duplication did not carry -@@ -342,9 +342,9 @@ static void torture_pki_ecdsa_duplicate_then_demote(void **state) - assert_true(rc == 0); - assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid); - -- ssh_key_free(pubkey); -- ssh_key_free(privkey); -- ssh_key_free(privkey_dup); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(privkey_dup); - } - - static void torture_pki_generate_key_ecdsa(void **state) -@@ -373,8 +373,7 @@ static void torture_pki_generate_key_ecdsa(void **state) - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key); - assert_true(rc == SSH_OK); -@@ -391,8 +390,7 @@ static void torture_pki_generate_key_ecdsa(void **state) - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key); - assert_true(rc == SSH_OK); -@@ -409,8 +407,7 @@ static void torture_pki_generate_key_ecdsa(void **state) - assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - ssh_free(session); - } -@@ -451,8 +448,8 @@ static void torture_pki_ecdsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - - /* Test with passphrase */ - rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY_PASSPHRASE, -@@ -489,8 +486,8 @@ static void torture_pki_ecdsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - } - #endif /* HAVE_LIBCRYPTO */ - -@@ -508,7 +505,7 @@ static void torture_pki_ecdsa_name(void **state, const char *expected_name) - etype_char =ssh_pki_key_ecdsa_name(key); - assert_true(strcmp(etype_char, expected_name) == 0); - -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ecdsa_name256(void **state) -diff --git a/tests/unittests/torture_pki_ed25519.c b/tests/unittests/torture_pki_ed25519.c -index 39012168..a4b147bf 100644 ---- a/tests/unittests/torture_pki_ed25519.c -+++ b/tests/unittests/torture_pki_ed25519.c -@@ -62,7 +62,7 @@ static void torture_pki_ed25519_import_pubkey_file(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state) -@@ -77,7 +77,7 @@ static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ed25519_import_privkey_base64(void **state) -@@ -106,7 +106,7 @@ static void torture_pki_ed25519_import_privkey_base64(void **state) - assert_true(rc == 1); - - free(key_str); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - - } - -@@ -141,7 +141,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state) - NULL, - &b64_key); - assert_return_code(rc, errno); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - - rc = ssh_pki_import_privkey_base64(b64_key, - passphrase, -@@ -157,7 +157,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state) - assert_true(rc == 1); - - SSH_STRING_FREE_CHAR(b64_key); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ed25519_publickey_from_privatekey(void **state) -@@ -184,8 +184,8 @@ static void torture_pki_ed25519_publickey_from_privatekey(void **state) - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - -- ssh_key_free(key); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ed25519_publickey_base64(void **state) -@@ -222,7 +222,7 @@ static void torture_pki_ed25519_publickey_base64(void **state) - - free(b64_key); - free(key_buf); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state) -@@ -261,8 +261,8 @@ static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state) - pubkey_generated, - len); - -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_ed25519_generate_key(void **state) -@@ -293,8 +293,7 @@ static void torture_pki_ed25519_generate_key(void **state) - assert_true(rc == SSH_ERROR); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key=NULL; -+ SSH_KEY_FREE(key); - - ssh_free(session); - } -@@ -336,7 +335,7 @@ static void torture_pki_ed25519_write_privkey(void **state) - assert_true(rc == 0); - - unlink(LIBSSH_ED25519_TESTKEY); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(privkey); - /* do the same with passphrase */ - rc = ssh_pki_export_privkey_file(origkey, - torture_get_testkey_passphrase(), -@@ -365,8 +364,8 @@ static void torture_pki_ed25519_write_privkey(void **state) - assert_true(rc == 0); - unlink(LIBSSH_ED25519_TESTKEY); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - - /* Test with passphrase */ - rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY_PASSPHRASE, -@@ -404,8 +403,8 @@ static void torture_pki_ed25519_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - } - - static void torture_pki_ed25519_sign(void **state) -@@ -441,8 +440,8 @@ static void torture_pki_ed25519_sign(void **state) - assert_memory_equal(ssh_string_data(blob), ref_signature, sizeof(ref_signature)); - /* ssh_print_hexa("signature", ssh_string_data(blob), ssh_string_len(blob)); */ - ssh_signature_free(sig); -- ssh_key_free(privkey); -- ssh_string_free(blob); -+ SSH_KEY_FREE(privkey); -+ SSH_STRING_FREE(blob); - - } - -@@ -473,8 +472,8 @@ static void torture_pki_ed25519_verify(void **state){ - ssh_signature_free(sig); - /* alter signature and expect false result */ - -- ssh_key_free(pubkey); -- ssh_string_free(blob); -+ SSH_KEY_FREE(pubkey); -+ SSH_STRING_FREE(blob); - free(pkey_ptr); - } - -@@ -509,8 +508,8 @@ static void torture_pki_ed25519_verify_bad(void **state){ - ssh_signature_free(sig); - - } -- ssh_key_free(pubkey); -- ssh_string_free(blob); -+ SSH_KEY_FREE(pubkey); -+ SSH_STRING_FREE(blob); - free(pkey_ptr); - } - -@@ -535,8 +534,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(testkey, -@@ -545,7 +543,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_ed25519_privkey_dup(void **state) -@@ -572,8 +570,8 @@ static void torture_pki_ed25519_privkey_dup(void **state) - dup = ssh_key_dup(key); - assert_non_null(dup); - -- ssh_key_free(key); -- ssh_key_free(dup); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(dup); - } - - static void torture_pki_ed25519_pubkey_dup(void **state) -@@ -609,8 +607,8 @@ static void torture_pki_ed25519_pubkey_dup(void **state) - assert_true(rc == 1); - - SAFE_FREE(pub_str); -- ssh_key_free(pubkey); -- ssh_key_free(dup); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(dup); - } - - int torture_run_tests(void) { -diff --git a/tests/unittests/torture_pki_rsa.c b/tests/unittests/torture_pki_rsa.c -index 0d5e97fa..15ad6466 100644 ---- a/tests/unittests/torture_pki_rsa.c -+++ b/tests/unittests/torture_pki_rsa.c -@@ -84,7 +84,7 @@ static void torture_pki_rsa_import_pubkey_file(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state) -@@ -99,7 +99,7 @@ static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_rsa_import_privkey_base64_NULL_key(void **state) -@@ -131,7 +131,7 @@ static void torture_pki_rsa_import_privkey_base64_NULL_str(void **state) - rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); - assert_true(rc == -1); - -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_rsa_import_privkey_base64(void **state) -@@ -160,7 +160,7 @@ static void torture_pki_rsa_import_privkey_base64(void **state) - assert_true(rc == 1); - - free(key_str); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_rsa_publickey_from_privatekey(void **state) -@@ -185,8 +185,8 @@ static void torture_pki_rsa_publickey_from_privatekey(void **state) - rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey); - assert_true(rc == SSH_OK); - -- ssh_key_free(key); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_rsa_copy_cert_to_privkey(void **state) -@@ -239,9 +239,9 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state) - rc = ssh_pki_copy_cert_to_privkey(cert, privkey); - assert_true(rc == SSH_ERROR); - -- ssh_key_free(cert); -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(cert); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_rsa_import_cert_file(void **state) { -@@ -260,7 +260,7 @@ static void torture_pki_rsa_import_cert_file(void **state) { - rc = ssh_key_is_public(cert); - assert_true(rc == 1); - -- ssh_key_free(cert); -+ SSH_KEY_FREE(cert); - } - - static void torture_pki_rsa_publickey_base64(void **state) -@@ -297,7 +297,7 @@ static void torture_pki_rsa_publickey_base64(void **state) - - free(b64_key); - free(key_buf); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - } - - static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) { -@@ -335,8 +335,8 @@ static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) { - pubkey_generated, - len); - -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - } - - static void torture_pki_rsa_duplicate_key(void **state) -@@ -356,7 +356,7 @@ static void torture_pki_rsa_duplicate_key(void **state) - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, -@@ -382,11 +382,11 @@ static void torture_pki_rsa_duplicate_key(void **state) - rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(pubkey); -- ssh_key_free(privkey); -- ssh_key_free(privkey_dup); -- ssh_string_free_char(b64_key); -- ssh_string_free_char(b64_key_gen); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(privkey_dup); -+ SSH_STRING_FREE_CHAR(b64_key); -+ SSH_STRING_FREE_CHAR(b64_key_gen); - } - - static void torture_pki_rsa_generate_key(void **state) -@@ -405,7 +405,7 @@ static void torture_pki_rsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,RSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); -@@ -416,7 +416,7 @@ static void torture_pki_rsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,RSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - key=NULL; - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key); -@@ -427,7 +427,7 @@ static void torture_pki_rsa_generate_key(void **state) - rc = pki_signature_verify(session,sign,key,RSA_HASH,20); - assert_true(rc == SSH_OK); - ssh_signature_free(sign); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - key=NULL; - - ssh_free(session); -@@ -477,7 +477,7 @@ static void torture_pki_rsa_sha2(void **state) - ssh_signature_free(sign); - - /* Cleanup */ -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - ssh_free(session); - } - -@@ -518,8 +518,8 @@ static void torture_pki_rsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - - /* Test with passphrase */ - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY_PASSPHRASE, -@@ -557,8 +557,8 @@ static void torture_pki_rsa_write_privkey(void **state) - rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE); - assert_true(rc == 0); - -- ssh_key_free(origkey); -- ssh_key_free(privkey); -+ SSH_KEY_FREE(origkey); -+ SSH_KEY_FREE(privkey); - } - #endif /* HAVE_LIBCRYPTO */ - -@@ -581,8 +581,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), -@@ -591,8 +590,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - #ifndef HAVE_LIBCRYPTO - /* test if it returns -1 if passphrase is NULL */ -@@ -603,8 +601,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - #endif - } - -@@ -631,8 +628,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(keystring, -@@ -641,8 +637,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is NULL */ - /* libcrypto asks for a passphrase, so skip this test */ -@@ -652,8 +647,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - } - - int torture_run_tests(void) { -diff --git a/tests/unittests/torture_threads_buffer.c b/tests/unittests/torture_threads_buffer.c -index e3cebdc9..2e6f30b6 100644 ---- a/tests/unittests/torture_threads_buffer.c -+++ b/tests/unittests/torture_threads_buffer.c -@@ -87,7 +87,7 @@ static void *thread_growing_buffer(void *threadid) - } - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -134,14 +134,14 @@ static void *thread_growing_buffer_shifting(void *threadid) - if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) { - assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated); - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - } - } - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -198,7 +198,7 @@ static void *thread_buffer_prepend(void *threadid) - assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10); - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -247,9 +247,9 @@ static void *thread_ssh_buffer_get_ssh_string(void *threadid) - for (l = 0; l < k; ++l) { - ssh_string str = ssh_buffer_get_ssh_string(buffer); - assert_null(str); -- ssh_string_free(str); -+ SSH_STRING_FREE(str); - } -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - } - } - } -@@ -316,10 +316,10 @@ static void *thread_ssh_buffer_add_format(void *threadid) - assert_int_equal(len, sizeof(verif) - 1); - assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1); - -- ssh_string_free(s); -+ SSH_STRING_FREE(s); - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -397,7 +397,7 @@ static void *thread_ssh_buffer_get_format(void *threadid) { - SAFE_FREE(s2); - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -458,7 +458,7 @@ static void *thread_ssh_buffer_get_format_error(void *threadid) - assert_true(s2 == NULL); - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -@@ -514,7 +514,7 @@ static void *thread_buffer_pack_badformat(void *threadid) - * it could crash the process */ - - /* Teardown */ -- ssh_buffer_free(buffer); -+ SSH_BUFFER_FREE(buffer); - pthread_exit(NULL); - } - -diff --git a/tests/unittests/torture_threads_pki_rsa.c b/tests/unittests/torture_threads_pki_rsa.c -index d19d8bbf..1313f566 100644 ---- a/tests/unittests/torture_threads_pki_rsa.c -+++ b/tests/unittests/torture_threads_pki_rsa.c -@@ -143,7 +143,7 @@ static void *thread_pki_rsa_import_pubkey_file(void *threadid) - assert_return_code(rc, errno); - assert_non_null(pubkey); - -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - - pthread_exit(NULL); - } -@@ -201,7 +201,7 @@ static void *thread_pki_rsa_import_privkey_base64_NULL_str(void *threadid) - rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key); - assert_true(rc == -1); - -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - pthread_exit(NULL); - } - -@@ -242,7 +242,7 @@ static void *thread_pki_rsa_import_privkey_base64(void *threadid) - assert_true(ok); - - free(key_str); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - - pthread_exit(NULL); - } -@@ -283,8 +283,8 @@ static void *thread_pki_rsa_publickey_from_privatekey(void *threadid) - assert_true(rc == SSH_OK); - assert_non_null(pubkey); - -- ssh_key_free(key); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(key); -+ SSH_KEY_FREE(pubkey); - pthread_exit(NULL); - } - -@@ -349,9 +349,9 @@ static void *thread_pki_rsa_copy_cert_to_privkey(void *threadid) - rc = ssh_pki_copy_cert_to_privkey(cert, privkey); - assert_true(rc == SSH_ERROR); - -- ssh_key_free(cert); -- ssh_key_free(privkey); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(cert); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(pubkey); - pthread_exit(NULL); - } - -@@ -383,7 +383,7 @@ static void *thread_pki_rsa_import_cert_file(void *threadid) - rc = ssh_key_is_public(cert); - assert_true(rc == 1); - -- ssh_key_free(cert); -+ SSH_KEY_FREE(cert); - pthread_exit(NULL); - } - -@@ -432,7 +432,7 @@ static void *thread_pki_rsa_publickey_base64(void *threadid) - - free(b64_key); - free(key_buf); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - pthread_exit(NULL); - } - -@@ -464,7 +464,7 @@ static void *thread_pki_rsa_duplicate_key(void *threadid) - - rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key); - assert_true(rc == 0); -- ssh_key_free(pubkey); -+ SSH_KEY_FREE(pubkey); - - rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY, - NULL, -@@ -489,11 +489,11 @@ static void *thread_pki_rsa_duplicate_key(void *threadid) - cmp = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE); - assert_true(cmp == 0); - -- ssh_key_free(pubkey); -- ssh_key_free(privkey); -- ssh_key_free(privkey_dup); -- ssh_string_free_char(b64_key); -- ssh_string_free_char(b64_key_gen); -+ SSH_KEY_FREE(pubkey); -+ SSH_KEY_FREE(privkey); -+ SSH_KEY_FREE(privkey_dup); -+ SSH_STRING_FREE_CHAR(b64_key); -+ SSH_STRING_FREE_CHAR(b64_key_gen); - pthread_exit(NULL); - } - -@@ -531,8 +531,7 @@ static void *thread_pki_rsa_generate_key(void *threadid) - assert_ssh_return_code(session, rc); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key); - assert_ssh_return_code(session, rc); -@@ -545,8 +544,7 @@ static void *thread_pki_rsa_generate_key(void *threadid) - assert_ssh_return_code(session, rc); - - ssh_signature_free(sign); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - - rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key); -@@ -560,7 +558,7 @@ static void *thread_pki_rsa_generate_key(void *threadid) - assert_true(rc == SSH_OK); - - ssh_signature_free(sign); -- ssh_key_free(key); -+ SSH_KEY_FREE(key); - key = NULL; - - ssh_free(session); -@@ -596,8 +594,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid) - rc = ssh_key_is_private(key); - assert_true(rc == 1); - -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - /* test if it returns -1 if passphrase is wrong */ - rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1), -@@ -606,8 +603,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - - #ifndef HAVE_LIBCRYPTO - /* test if it returns -1 if passphrase is NULL */ -@@ -618,8 +614,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid) - NULL, - &key); - assert_true(rc == -1); -- ssh_key_free(key); -- key = NULL; -+ SSH_KEY_FREE(key); - #endif - pthread_exit(NULL); - } diff --git a/libssh-0.8.3-fixes-the-oss-fuzz-bug.patch b/libssh-0.8.3-fixes-the-oss-fuzz-bug.patch deleted file mode 100644 index 4fe330dabfa701464f299988dfe13a2f0afe8f0e..0000000000000000000000000000000000000000 --- a/libssh-0.8.3-fixes-the-oss-fuzz-bug.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 6ae097069ad8e4658f14870c4d23409b88139810 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 10 Dec 2019 18:09:51 +0800 -Subject: [PATCH] backport-fixes-the-oss-fuzz-bug - ---- - src/buffer.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - -diff --git a/src/buffer.c b/src/buffer.c -index da6e587..08529ee 100644 ---- a/src/buffer.c -+++ b/src/buffer.c -@@ -1112,6 +1112,7 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, - goto cleanup; - } - -+ rc = SSH_ERROR; - switch (*p) { - case 'b': - o.byte = va_arg(ap, uint8_t *); -@@ -1121,20 +1122,26 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, - case 'w': - o.word = va_arg(ap, uint16_t *); - rlen = ssh_buffer_get_data(buffer, o.word, sizeof(uint16_t)); -- *o.word = ntohs(*o.word); -- rc = rlen==2 ? SSH_OK : SSH_ERROR; -+ if (rlen == 2) { -+ *o.word = ntohs(*o.word); -+ rc = SSH_OK; -+ } - break; - case 'd': - o.dword = va_arg(ap, uint32_t *); - rlen = ssh_buffer_get_u32(buffer, o.dword); -- *o.dword = ntohl(*o.dword); -- rc = rlen==4 ? SSH_OK : SSH_ERROR; -+ if (rlen == 4) { -+ *o.dword = ntohl(*o.dword); -+ rc = SSH_OK; -+ } - break; - case 'q': - o.qword = va_arg(ap, uint64_t*); - rlen = ssh_buffer_get_u64(buffer, o.qword); -- *o.qword = ntohll(*o.qword); -- rc = rlen==8 ? SSH_OK : SSH_ERROR; -+ if (rlen == 8) { -+ *o.qword = ntohll(*o.qword); -+ rc = SSH_OK; -+ } - break; - case 'S': - o.string = va_arg(ap, ssh_string *); --- -2.19.1 - - diff --git a/libssh-0.8.3.tar.xz b/libssh-0.8.3.tar.xz deleted file mode 100644 index 8ed3e5f4e2927cdf4d3fdbb1bee984b5f2467e11..0000000000000000000000000000000000000000 Binary files a/libssh-0.8.3.tar.xz and /dev/null differ diff --git a/libssh-0.8.3.tar.xz.asc b/libssh-0.8.3.tar.xz.asc deleted file mode 100644 index 9b0543fc362af5abe52b649d2e7ec2eb0dd30ef0..0000000000000000000000000000000000000000 --- a/libssh-0.8.3.tar.xz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAlukpGkACgkQfuD8TcwB -Tj3qsA//bPS3hYBbKIChg1+o2s/lAbkjV6mv5LR9gyTljjUAikFNf/AN/yrNLD/H -0sAAD8S2Mj5t4+daUronpX9IJPZtimFB3WoBl+S9J9ybyzpgsspTNv0KZt/O9Vt+ -QamOYkMXDtDcqUCHxIzURKiIc6ATsobiUx6EhWOSa8fFsnW6golCJtHzHi5fKsPF -x92J5gZ4jUehZJEiX/LmqFCblLK5qV8g/F+TauWg9jL5m0SNuR0gfDxi3VNV+yeG -gCtneHNrg/Jq9PwI71dIAQ+EDxYARBrLRe7zNSJgZHNuHttyVZaObgO/tFGzAwfj -g+9cuBTHvkKbgM0CodT9ftmdXU8Gt2/3yugfP/FSHUKCy9YgOM5Yo+T8lhAw3Pnt -5ZienZztJwBabui7rWeebhaBSFNuaFUhp1V5HOBT1YjKWlr3yqSGs2PmYYA7Ioeq -ulcyUsNZFXj7hALCxhyBfcwz+USWBpjuxZz5gK5uXbwWcxZUkiRTCXprKiN8jUn/ -1/wteO4inm3dpKM3oMuxsk6c64JZnbXkD9vPEP7Fv48nPVVcqs+jk5RPK7iOBUgd -bglc6F05cnUzFz78Lj/FIgEqdYV/vGtxxpwOCRPBDhDWvjbDltN7GkcKQ7ItNd9L -UpMir12LL1Lo32IWxH457dKSCut2/+wGGLcXjUMMhhs/6UDqerg= -=uDol ------END PGP SIGNATURE----- diff --git a/libssh-0.9.4-fix-version.patch b/libssh-0.9.4-fix-version.patch new file mode 100644 index 0000000000000000000000000000000000000000..143e9727f09c444299dab8f30d2d421a235e5331 --- /dev/null +++ b/libssh-0.9.4-fix-version.patch @@ -0,0 +1,11 @@ +--- a/include/libssh/libssh.h 2020-04-15 13:38:32.899177005 +0200 ++++ b/include/libssh/libssh.h 2020-04-15 13:38:57.406454427 +0200 +@@ -79,7 +79,7 @@ + /* libssh version */ + #define LIBSSH_VERSION_MAJOR 0 + #define LIBSSH_VERSION_MINOR 9 +-#define LIBSSH_VERSION_MICRO 3 ++#define LIBSSH_VERSION_MICRO 4 + + #define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \ + LIBSSH_VERSION_MINOR, \ diff --git a/libssh-0.9.4.tar.xz b/libssh-0.9.4.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..8c8bed0355b44341dcc20bb83880c3014bda987b Binary files /dev/null and b/libssh-0.9.4.tar.xz differ diff --git a/libssh-0.9.4.tar.xz.asc b/libssh-0.9.4.tar.xz.asc new file mode 100644 index 0000000000000000000000000000000000000000..84b673cae1cd3f70af04dd125332d6af87b648c2 --- /dev/null +++ b/libssh-0.9.4.tar.xz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAl6O0BgACgkQfuD8TcwB +Tj0dCQ/+J0pjZU6uu7h6gkc4BbRciCpYDIv66Lw9iCc2bQmLLhPrukWjz6/PDV+U +iL/1dlwxG8rOlXdtCEFGyDvm0y4E8NaQCcgjU9jA8nsXo+SyyJAeWT7BeI3m2hPi +tjbLAjQVHCW1jIite1dJeoPIPg15LChc08t+HWVI3pwQviwlJWTPmHgMaT3uwa1X +fD66hjgB2UFo5eYnbION3L/jpA0vsI4o4F5CFPEhgbz3H6KmrgQbKLPM3H/103zU +XjtHEw7gy/85OmjpcskMrUVAMbw9EZ5ESFOrKyuQaFBY57L//tAdUaEloxsMKt+5 +nmYunmlGmDLT6rHfjSg5X1S+NsQaXhGelc0TLVgvlzs4kR+QbApR1ewKTcsYlVwr +jYG+PuAiROqc18xM/fQYh8UqohluDBmUpEDmVOEKT2tg/S7R5RJtOxdmcZPsLO+W +EOoP+OeUvQqNlzqu6kBRI4v2lwVU4QwDzKCNRzwQHJOH+azH/3FRJBDF1ZAQvgxy +w/NqlpFO6P76e0SLzBjHCDyqwbAzfq4WK3f5oE0RAA5RlndWusovTAWaYrAbVaoz +emkt/guiHHsbLy6S2ELJu4BI9TGGtDMJoo1ScMMQzFqijUISCBgK/+6mUVUlMli0 +lTH6VE+MvpElADE+IYSXWOLHrspTxVa/jVun3iYE8Nexn6G0XE0= +=xSu8 +-----END PGP SIGNATURE----- diff --git a/libssh-stable-0p8-CVE-2018-10933-part1.patch b/libssh-stable-0p8-CVE-2018-10933-part1.patch deleted file mode 100644 index 1a60e73f83499f1d960a2b866d888c6742e8842d..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part1.patch +++ /dev/null @@ -1,130 +0,0 @@ -From b166ac4749c78f475b1708f0345e6ca2749c5d6d Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Mon, 10 Sep 2018 17:37:42 +0200 -Subject: CVE-2018-10933: Introduced new auth states - -Introduced the states SSH_AUTH_STATE_PUBKEY_OFFER_SENT and -SSH_AUTH_STATE_PUBKEY_AUTH_SENT to know when SSH2_MSG_USERAUTH_PK_OK and -SSH2_MSG_USERAUTH_SUCCESS should be expected. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - include/libssh/auth.h | 4 ++++ - src/auth.c | 44 +++++++++++++++++++++++++++----------------- - 2 files changed, 31 insertions(+), 17 deletions(-) - -diff --git a/include/libssh/auth.h b/include/libssh/auth.h -index 3913f219..8daab47d 100644 ---- a/include/libssh/auth.h -+++ b/include/libssh/auth.h -@@ -76,6 +76,10 @@ enum ssh_auth_state_e { - SSH_AUTH_STATE_GSSAPI_TOKEN, - /** We have sent the MIC and expecting to be authenticated */ - SSH_AUTH_STATE_GSSAPI_MIC_SENT, -+ /** We have offered a pubkey to check if it is supported */ -+ SSH_AUTH_STATE_PUBKEY_OFFER_SENT, -+ /** We have sent pubkey and signature expecting to be authenticated */ -+ SSH_AUTH_STATE_PUBKEY_AUTH_SENT, - }; - - /** @internal -diff --git a/src/auth.c b/src/auth.c -index 97b6a6e1..41b76aa6 100644 ---- a/src/auth.c -+++ b/src/auth.c -@@ -85,6 +85,8 @@ static int ssh_auth_response_termination(void *user) { - case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: - case SSH_AUTH_STATE_GSSAPI_TOKEN: - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: -+ case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: -+ case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: - return 0; - default: - return 1; -@@ -167,6 +169,8 @@ static int ssh_userauth_get_response(ssh_session session) { - case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT: - case SSH_AUTH_STATE_GSSAPI_TOKEN: - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: -+ case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: -+ case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: - case SSH_AUTH_STATE_NONE: - /* not reached */ - rc = SSH_AUTH_ERROR; -@@ -312,24 +316,30 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) { - SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) { - int rc; - -- SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE"); -- -- if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) { -- /* Assuming we are in keyboard-interactive context */ - SSH_LOG(SSH_LOG_TRACE, -- "keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST"); -- rc = ssh_packet_userauth_info_request(session,type,packet,user); -+ "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE"); -+ -+ if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) { -+ /* Assuming we are in keyboard-interactive context */ -+ SSH_LOG(SSH_LOG_TRACE, -+ "keyboard-interactive context, " -+ "assuming SSH_USERAUTH_INFO_REQUEST"); -+ rc = ssh_packet_userauth_info_request(session,type,packet,user); - #ifdef WITH_GSSAPI -- } else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) { -- rc = ssh_packet_userauth_gssapi_response(session, type, packet, user); -+ } else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) { -+ rc = ssh_packet_userauth_gssapi_response(session, type, packet, user); - #endif -- } else { -- session->auth.state = SSH_AUTH_STATE_PK_OK; -- SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK"); -- rc = SSH_PACKET_USED; -- } -+ } else if (session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT) { -+ session->auth.state = SSH_AUTH_STATE_PK_OK; -+ SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK"); -+ rc = SSH_PACKET_USED; -+ } else { -+ session->auth.state = SSH_AUTH_STATE_ERROR; -+ SSH_LOG(SSH_LOG_TRACE, "SSH_USERAUTH_PK_OK received in wrong state"); -+ rc = SSH_PACKET_USED; -+ } - -- return rc; -+ return rc; - } - - /** -@@ -553,7 +563,7 @@ int ssh_userauth_try_publickey(ssh_session session, - ssh_string_free(pubkey_s); - - session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; -- session->auth.state = SSH_AUTH_STATE_NONE; -+ session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY; - rc = ssh_packet_send(session); - if (rc == SSH_ERROR) { -@@ -701,7 +711,7 @@ int ssh_userauth_publickey(ssh_session session, - } - - session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; -- session->auth.state = SSH_AUTH_STATE_NONE; -+ session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY; - rc = ssh_packet_send(session); - if (rc == SSH_ERROR) { -@@ -797,7 +807,7 @@ static int ssh_userauth_agent_publickey(ssh_session session, - } - - session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY; -- session->auth.state = SSH_AUTH_STATE_NONE; -+ session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT; - rc = ssh_packet_send(session); - if (rc == SSH_ERROR) { --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part2.patch b/libssh-stable-0p8-CVE-2018-10933-part2.patch deleted file mode 100644 index de530b98325a4992af150c6c4cc3666c386bfd28..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part2.patch +++ /dev/null @@ -1,62 +0,0 @@ -From fcfba0d8aa15a0142e57513f271eb7fa4bbabc9a Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Mon, 10 Sep 2018 17:38:22 +0200 -Subject: CVE-2018-10933: Introduce SSH_AUTH_STATE_PASSWORD_AUTH_SENT - -The introduced auth state allows to identify when authentication using -password was tried. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - include/libssh/auth.h | 2 ++ - src/auth.c | 4 +++- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/include/libssh/auth.h b/include/libssh/auth.h -index 8daab47d..899282c1 100644 ---- a/include/libssh/auth.h -+++ b/include/libssh/auth.h -@@ -80,6 +80,8 @@ enum ssh_auth_state_e { - SSH_AUTH_STATE_PUBKEY_OFFER_SENT, - /** We have sent pubkey and signature expecting to be authenticated */ - SSH_AUTH_STATE_PUBKEY_AUTH_SENT, -+ /** We have sent a password expecting to be authenticated */ -+ SSH_AUTH_STATE_PASSWORD_AUTH_SENT, - }; - - /** @internal -diff --git a/src/auth.c b/src/auth.c -index 41b76aa6..2b06d2e1 100644 ---- a/src/auth.c -+++ b/src/auth.c -@@ -87,6 +87,7 @@ static int ssh_auth_response_termination(void *user) { - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: - case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: - case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: -+ case SSH_AUTH_STATE_PASSWORD_AUTH_SENT: - return 0; - default: - return 1; -@@ -171,6 +172,7 @@ static int ssh_userauth_get_response(ssh_session session) { - case SSH_AUTH_STATE_GSSAPI_MIC_SENT: - case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: - case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: -+ case SSH_AUTH_STATE_PASSWORD_AUTH_SENT: - case SSH_AUTH_STATE_NONE: - /* not reached */ - rc = SSH_AUTH_ERROR; -@@ -1268,7 +1270,7 @@ int ssh_userauth_password(ssh_session session, - } - - session->auth.current_method = SSH_AUTH_METHOD_PASSWORD; -- session->auth.state = SSH_AUTH_STATE_NONE; -+ session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD; - rc = ssh_packet_send(session); - if (rc == SSH_ERROR) { --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part3.patch b/libssh-stable-0p8-CVE-2018-10933-part3.patch deleted file mode 100644 index e70e5e7af1c71e6bf5284b24195bf8a2f38497a9..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part3.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 7819621fc2a07d2d4649b36ca77850610741cfec Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Wed, 19 Sep 2018 17:01:15 +0200 -Subject: CVE-2018-10933: Introduce SSH_AUTH_STATE_AUTH_NONE_SENT - -The introduced auth state allows to identify when a request without -authentication information was sent. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - include/libssh/auth.h | 2 ++ - src/auth.c | 4 +++- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/include/libssh/auth.h b/include/libssh/auth.h -index 899282c1..90b377d4 100644 ---- a/include/libssh/auth.h -+++ b/include/libssh/auth.h -@@ -82,6 +82,8 @@ enum ssh_auth_state_e { - SSH_AUTH_STATE_PUBKEY_AUTH_SENT, - /** We have sent a password expecting to be authenticated */ - SSH_AUTH_STATE_PASSWORD_AUTH_SENT, -+ /** We have sent a request without auth information (method 'none') */ -+ SSH_AUTH_STATE_AUTH_NONE_SENT, - }; - - /** @internal -diff --git a/src/auth.c b/src/auth.c -index 2b06d2e1..993e6dfe 100644 ---- a/src/auth.c -+++ b/src/auth.c -@@ -88,6 +88,7 @@ static int ssh_auth_response_termination(void *user) { - case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: - case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: - case SSH_AUTH_STATE_PASSWORD_AUTH_SENT: -+ case SSH_AUTH_STATE_AUTH_NONE_SENT: - return 0; - default: - return 1; -@@ -173,6 +174,7 @@ static int ssh_userauth_get_response(ssh_session session) { - case SSH_AUTH_STATE_PUBKEY_OFFER_SENT: - case SSH_AUTH_STATE_PUBKEY_AUTH_SENT: - case SSH_AUTH_STATE_PASSWORD_AUTH_SENT: -+ case SSH_AUTH_STATE_AUTH_NONE_SENT: - case SSH_AUTH_STATE_NONE: - /* not reached */ - rc = SSH_AUTH_ERROR; -@@ -428,7 +430,7 @@ int ssh_userauth_none(ssh_session session, const char *username) { - } - - session->auth.current_method = SSH_AUTH_METHOD_NONE; -- session->auth.state = SSH_AUTH_STATE_NONE; -+ session->auth.state = SSH_AUTH_STATE_AUTH_NONE_SENT; - session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE; - rc = ssh_packet_send(session); - if (rc == SSH_ERROR) { --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part4.patch b/libssh-stable-0p8-CVE-2018-10933-part4.patch deleted file mode 100644 index 6a9a6ed13a0488f5773e18a9f057ba75fd7990cc..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part4.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 72bce5ece7edc2fd8023185f9d47b9fc86ef4663 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Wed, 5 Sep 2018 12:14:07 +0200 -Subject: CVE-2018-10933: Set correct state after sending MIC - -After sending the client token, the auth state is set as -SSH_AUTH_STATE_GSSAPI_MIC_SENT. Then this can be expected to be the -state when a USERAUTH_FAILURE or USERAUTH_SUCCESS arrives. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - src/gssapi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/gssapi.c b/src/gssapi.c -index 51b69e7a..77df0b59 100644 ---- a/src/gssapi.c -+++ b/src/gssapi.c -@@ -960,8 +960,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){ - } - - if (maj_stat == GSS_S_COMPLETE) { -- session->auth.state = SSH_AUTH_STATE_NONE; - ssh_gssapi_send_mic(session); -+ session->auth.state = SSH_AUTH_STATE_GSSAPI_MIC_SENT; - } - - return SSH_PACKET_USED; --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part5.patch b/libssh-stable-0p8-CVE-2018-10933-part5.patch deleted file mode 100644 index 91c73aaf7ca40218390ec8e0091d177367eec6e2..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part5.patch +++ /dev/null @@ -1,39 +0,0 @@ -From adeaa69cc535827ec8acfbaf3ff91224b5a595a7 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Fri, 7 Sep 2018 17:00:40 +0200 -Subject: CVE-2018-10933: Check channel state when OPEN_CONFIRMATION arrives - -When a SSH2_MSG_OPEN_CONFIRMATION arrives, the channel state is checked -to be in SSH_CHANNEL_STATE_OPENING. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - src/channels.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/channels.c b/src/channels.c -index 103009a8..b26f6bd4 100644 ---- a/src/channels.c -+++ b/src/channels.c -@@ -171,6 +171,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){ - "Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d", - channel->local_channel, - channel->remote_channel); -+ -+ if (channel->state != SSH_CHANNEL_STATE_OPENING) { -+ SSH_LOG(SSH_LOG_RARE, -+ "SSH2_MSG_CHANNEL_OPEN_CONFIRMATION received in incorrect " -+ "channel state %d", -+ channel->state); -+ goto error; -+ } -+ - SSH_LOG(SSH_LOG_PROTOCOL, - "Remote window : %lu, maxpacket : %lu", - (long unsigned int) channel->remote_window, --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part6.patch b/libssh-stable-0p8-CVE-2018-10933-part6.patch deleted file mode 100644 index b25cc8843188544157cb858ba9f9959adb662676..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part6.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f8c452cbef228b105dcb757d7554c3388a4dbea5 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Fri, 7 Sep 2018 17:12:01 +0200 -Subject: CVE-2018-10933: Check channel state when OPEN_FAILURE arrives - -When a SSH2_MSG_OPEN_FAILURE arrives, the channel state is checked -to be in SSH_CHANNEL_STATE_OPENING. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - src/channels.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/channels.c b/src/channels.c -index b26f6bd4..0e61e5cd 100644 ---- a/src/channels.c -+++ b/src/channels.c -@@ -220,6 +220,14 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){ - return SSH_PACKET_USED; - } - -+ if (channel->state != SSH_CHANNEL_STATE_OPENING) { -+ SSH_LOG(SSH_LOG_RARE, -+ "SSH2_MSG_CHANNEL_OPEN_FAILURE received in incorrect channel " -+ "state %d", -+ channel->state); -+ goto error; -+ } -+ - ssh_set_error(session, SSH_REQUEST_DENIED, - "Channel opening failure: channel %u error (%lu) %s", - channel->local_channel, -@@ -228,6 +236,10 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){ - SAFE_FREE(error); - channel->state=SSH_CHANNEL_STATE_OPEN_DENIED; - return SSH_PACKET_USED; -+ -+error: -+ ssh_set_error(session, SSH_FATAL, "Invalid packet"); -+ return SSH_PACKET_USED; - } - - static int ssh_channel_open_termination(void *c){ --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part7.patch b/libssh-stable-0p8-CVE-2018-10933-part7.patch deleted file mode 100644 index 9b5174703b101c267fcf783cc5359ee8500e1500..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part7.patch +++ /dev/null @@ -1,871 +0,0 @@ -From 203818608ac8a83d68098f008306c3a568ac4cac Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Tue, 28 Aug 2018 18:13:03 +0200 -Subject: CVE-2018-10933: Introduced packet filtering - -The packet filter checks required states for the incoming packets and -reject them if they arrived in the wrong state. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - include/libssh/packet.h | 6 + - src/packet.c | 809 +++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 813 insertions(+), 2 deletions(-) - -diff --git a/include/libssh/packet.h b/include/libssh/packet.h -index a3bcb9a8..fbe09700 100644 ---- a/include/libssh/packet.h -+++ b/include/libssh/packet.h -@@ -43,6 +43,12 @@ enum ssh_packet_state_e { - PACKET_STATE_PROCESSING - }; - -+enum ssh_packet_filter_result_e { -+ SSH_PACKET_UNKNOWN, -+ SSH_PACKET_ALLOWED, -+ SSH_PACKET_DENIED -+}; -+ - int ssh_packet_send(ssh_session session); - - SSH_PACKET_CALLBACK(ssh_packet_unimplemented); -diff --git a/src/packet.c b/src/packet.c -index aa2f17f0..0b070fd4 100644 ---- a/src/packet.c -+++ b/src/packet.c -@@ -128,6 +128,797 @@ static ssh_packet_callback default_packet_handlers[]= { - ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100 - }; - -+/** @internal -+ * @brief check if the received packet is allowed for the current session state -+ * @param session current ssh_session -+ * @returns SSH_PACKET_ALLOWED if the packet is allowed; SSH_PACKET_DENIED -+ * if the packet arrived in wrong state; SSH_PACKET_UNKNOWN if the packet type -+ * is unknown -+ */ -+static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session session) -+{ -+ enum ssh_packet_filter_result_e rc; -+ -+#ifdef DEBUG_PACKET -+ SSH_LOG(SSH_LOG_PACKET, "Filtering packet type %d", -+ session->in_packet.type); -+#endif -+ -+ switch(session->in_packet.type) { -+ case SSH2_MSG_DISCONNECT: // 1 -+ /* -+ * States required: -+ * - None -+ * -+ * Transitions: -+ * - session->socket->state = SSH_SOCKET_CLOSED -+ * - session->session_state = SSH_SESSION_STATE_ERROR -+ * */ -+ -+ /* Always allowed */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_IGNORE: // 2 -+ /* -+ * States required: -+ * - None -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ /* Always allowed */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_UNIMPLEMENTED: // 3 -+ /* -+ * States required: -+ * - None -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ /* Always allowed */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_DEBUG: // 4 -+ /* -+ * States required: -+ * - None -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ /* Always allowed */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_SERVICE_REQUEST: // 5 -+ /* Server only */ -+ -+ /* -+ * States required: -+ * - session->session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * or session->session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - session->dh_handshake_state == DH_STATE_FINISHED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ /* If this is a client, reject the message */ -+ if (session->client) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) && -+ (session->session_state != SSH_SESSION_STATE_AUTHENTICATED)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_SERVICE_ACCEPT: // 6 -+ /* -+ * States required: -+ * - session->session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * or session->session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - session->dh_handshake_state == DH_STATE_FINISHED -+ * - session->auth.service_state == SSH_AUTH_SERVICE_SENT -+ * -+ * Transitions: -+ * - auth.service_state = SSH_AUTH_SERVICE_ACCEPTED -+ * */ -+ -+ if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) && -+ (session->session_state != SSH_SESSION_STATE_AUTHENTICATED)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ /* TODO check if only auth service can be requested */ -+ if (session->auth.service_state != SSH_AUTH_SERVICE_SENT) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_EXT_INFO: // 7 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - dh_handshake_state == DH_STATE_FINISHED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEXINIT: // 20 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * or session_state == SSH_SESSION_STATE_INITIAL_KEX -+ * - dh_handshake_state == DH_STATE_INIT -+ * or dh_handshake_state == DH_STATE_FINISHED (re-exchange) -+ * -+ * Transitions: -+ * - session->dh_handshake_state = DH_STATE_INIT -+ * - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED -+ * -+ * On server: -+ * - session->session_state = SSH_SESSION_STATE_DH -+ * */ -+ -+ if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATED) && -+ (session->session_state != SSH_SESSION_STATE_INITIAL_KEX)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if ((session->dh_handshake_state != DH_STATE_INIT) && -+ (session->dh_handshake_state != DH_STATE_FINISHED)) -+ { -+ rc = SSH_PACKET_DENIED; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_NEWKEYS: // 21 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_DH -+ * - dh_handshake_state == DH_STATE_NEWKEYS_SENT -+ * -+ * Transitions: -+ * - session->dh_handshake_state = DH_STATE_FINISHED -+ * - session->session_state = SSH_SESSION_STATE_AUTHENTICATING -+ * if session->flags & SSH_SESSION_FLAG_AUTHENTICATED -+ * - session->session_state = SSH_SESSION_STATE_AUTHENTICATED -+ * */ -+ -+ /* If DH has not been started, reject message */ -+ if (session->session_state != SSH_SESSION_STATE_DH) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ /* Only allowed if dh_handshake_state is in NEWKEYS_SENT state */ -+ if (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEXDH_INIT: // 30 -+ // SSH2_MSG_KEX_ECDH_INIT: // 30 -+ // SSH2_MSG_ECMQV_INIT: // 30 -+ // SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: // 30 -+ -+ /* Server only */ -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_DH -+ * - dh_handshake_state == DH_STATE_INIT -+ * -+ * Transitions: -+ * - session->dh_handshake_state = DH_STATE_INIT_SENT -+ * then calls dh_handshake_server which triggers: -+ * - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_DH) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ /* Only allowed if dh_handshake_state is in initial state */ -+ if (session->dh_handshake_state != DH_STATE_INIT) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEXDH_REPLY: // 31 -+ // SSH2_MSG_KEX_ECDH_REPLY: // 31 -+ // SSH2_MSG_ECMQV_REPLY: // 31 -+ // SSH2_MSG_KEX_DH_GEX_GROUP: // 31 -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_DH -+ * - dh_handshake_state == DH_STATE_INIT_SENT -+ * -+ * Transitions: -+ * - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_DH) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_INIT_SENT) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEX_DH_GEX_INIT: // 32 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEX_DH_GEX_REPLY: // 33 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_REQUEST: // 50 -+ /* Server only */ -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - dh_hanshake_state == DH_STATE_FINISHED -+ * -+ * Transitions: -+ * - if authentication was successful: -+ * - session_state = SSH_SESSION_STATE_AUTHENTICATED -+ * */ -+ -+ /* If this is a client, reject the message */ -+ if (session->client) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_FAILURE: // 51 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - dh_hanshake_state == DH_STATE_FINISHED -+ * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT -+ * or session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT -+ * or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT -+ * or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT -+ * or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT -+ * -+ * Transitions: -+ * - if unpacking failed: -+ * - session->auth.state = SSH_AUTH_ERROR -+ * - if failure was partial: -+ * - session->auth.state = SSH_AUTH_PARTIAL -+ * - else: -+ * - session->auth.state = SSH_AUTH_STATE_FAILED -+ * */ -+ -+ /* If this is a server, reject the message */ -+ if (session->server) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_SUCCESS: // 52 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - dh_hanshake_state == DH_STATE_FINISHED -+ * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT -+ * or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT -+ * or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT -+ * or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT -+ * or session->auth.state == SSH_AUTH_STATE_AUTH_NONE_SENT -+ * -+ * Transitions: -+ * - session->auth.state = SSH_AUTH_STATE_SUCCESS -+ * - session->session_state = SSH_SESSION_STATE_AUTHENTICATED -+ * - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED -+ * - sessions->auth.current_method = SSH_AUTH_METHOD_UNKNOWN -+ * */ -+ -+ /* If this is a server, reject the message */ -+ if (session->server) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_PUBKEY_AUTH_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_PASSWORD_AUTH_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_GSSAPI_MIC_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_AUTH_NONE_SENT)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_BANNER: // 53 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_PK_OK: // 60 -+ // SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // 60 -+ // SSH2_MSG_USERAUTH_INFO_REQUEST: // 60 -+ // SSH2_MSG_USERAUTH_GSSAPI_RESPONSE: // 60 -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT -+ * or -+ * session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT -+ * or -+ * session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT -+ * -+ * Transitions: -+ * Depending on the current state, the message is treated -+ * differently: -+ * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT -+ * - session->auth.state = SSH_AUTH_STATE_INFO -+ * - session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT -+ * - session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN -+ * - session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT -+ * - session->auth.state = SSH_AUTH_STATE_PK_OK -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_PUBKEY_OFFER_SENT) && -+ (session->auth.state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_INFO_RESPONSE: // 61 -+ // SSH2_MSG_USERAUTH_GSSAPI_TOKEN: // 61 -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - session_state->auth.state == SSH_SESSION_STATE_GSSAPI_TOKEN -+ * or -+ * session_state->auth.state == SSH_SESSION_STATE_INFO -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if ((session->auth.state != SSH_AUTH_STATE_INFO) && -+ (session->auth.state != SSH_AUTH_STATE_GSSAPI_TOKEN)) -+ { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE: // 63 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_GSSAPI_ERROR: // 64 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_GSSAPI_ERRTOK: // 65 -+ /* TODO Not filtered */ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_USERAUTH_GSSAPI_MIC: // 66 -+ /* Server only */ -+ -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATING -+ * - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC -+ * -+ * Transitions: -+ * Depending on the result of the verification, the states are -+ * changed: -+ * - SSH_AUTH_SUCCESS: -+ * - session->session_state = SSH_SESSION_STATE_AUTHENTICATED -+ * - session->flags != SSH_SESSION_FLAG_AUTHENTICATED -+ * - SSH_AUTH_PARTIAL: -+ * - None -+ * - any other case: -+ * - None -+ * */ -+ -+ /* If this is a client, reject the message */ -+ if (session->client) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->dh_handshake_state != DH_STATE_FINISHED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_GLOBAL_REQUEST: // 80 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_REQUEST_SUCCESS: // 81 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING -+ * -+ * Transitions: -+ * - session->global_req_state == SSH_CHANNEL_REQ_STATE_ACCEPTED -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_REQUEST_FAILURE: // 82 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING -+ * -+ * Transitions: -+ * - session->global_req_state == SSH_CHANNEL_REQ_STATE_DENIED -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_OPEN: // 90 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: // 91 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - channel->state = SSH_CHANNEL_STATE_OPEN -+ * - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_OPEN_FAILURE: // 92 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - channel->state = SSH_CHANNEL_STATE_OPEN_DENIED -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_WINDOW_ADJUST: // 93 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_DATA: // 94 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_EXTENDED_DATA: // 95 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_EOF: // 96 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - None -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_CLOSE: // 97 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - channel->state = SSH_CHANNEL_STATE_CLOSED -+ * - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_REQUEST: // 98 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * -+ * Transitions: -+ * - Depends on the request -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_SUCCESS: // 99 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING -+ * -+ * Transitions: -+ * - channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ case SSH2_MSG_CHANNEL_FAILURE: // 100 -+ /* -+ * States required: -+ * - session_state == SSH_SESSION_STATE_AUTHENTICATED -+ * - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING -+ * -+ * Transitions: -+ * - channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED -+ * */ -+ -+ if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) { -+ rc = SSH_PACKET_DENIED; -+ break; -+ } -+ -+ rc = SSH_PACKET_ALLOWED; -+ break; -+ default: -+ /* Unknown message, do not filter */ -+ rc = SSH_PACKET_UNKNOWN; -+ goto end; -+ } -+ -+end: -+#ifdef DEBUG_PACKET -+ if (rc == SSH_PACKET_DENIED) { -+ SSH_LOG(SSH_LOG_PACKET, "REJECTED packet type %d: ", -+ session->in_packet.type); -+ } -+ -+ if (rc == SSH_PACKET_UNKNOWN) { -+ SSH_LOG(SSH_LOG_PACKET, "UNKNOWN packet type %d", -+ session->in_packet.type); -+ } -+#endif -+ -+ return rc; -+} -+ - /* in nonblocking mode, socket_read will read as much as it can, and return */ - /* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */ - /* in blocking mode, it will read at least len bytes and will block until it's ok. */ -@@ -158,6 +949,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) - uint32_t packet_len, compsize, payloadsize; - uint8_t padding; - size_t processed = 0; /* number of byte processed from the callback */ -+ enum ssh_packet_filter_result_e filter_result; - - if(session->current_crypto != NULL) { - current_macsize = hmac_digest_len(session->current_crypto->in_hmac); -@@ -345,8 +1137,21 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) - "packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]", - session->in_packet.type, packet_len, padding, compsize, payloadsize); - -- /* Execute callbacks */ -- ssh_packet_process(session, session->in_packet.type); -+ /* Check if the packet is expected */ -+ filter_result = ssh_packet_incoming_filter(session); -+ -+ switch(filter_result) { -+ case SSH_PACKET_ALLOWED: -+ /* Execute callbacks */ -+ ssh_packet_process(session, session->in_packet.type); -+ break; -+ case SSH_PACKET_DENIED: -+ goto error; -+ case SSH_PACKET_UNKNOWN: -+ ssh_packet_send_unimplemented(session, session->recv_seq - 1); -+ break; -+ } -+ - session->packet_state = PACKET_STATE_INIT; - if (processed < receivedlen) { - /* Handle a potential packet left in socket buffer */ --- -cgit v1.2.1 - diff --git a/libssh-stable-0p8-CVE-2018-10933-part8.patch b/libssh-stable-0p8-CVE-2018-10933-part8.patch deleted file mode 100644 index 8ef331c844d9cab5ea770e71bd335a35402e50eb..0000000000000000000000000000000000000000 --- a/libssh-stable-0p8-CVE-2018-10933-part8.patch +++ /dev/null @@ -1,543 +0,0 @@ -From 09a7638575b3c07ad227763e1f03f7553b045e79 Mon Sep 17 00:00:00 2001 -From: Anderson Toshiyuki Sasaki -Date: Fri, 7 Sep 2018 15:26:49 +0200 -Subject: CVE-2018-10933: Add tests for packet filtering - -Created the test torture_packet_filter.c which tests if packets are -being correctly filtered. - -Fixes T101 - -Signed-off-by: Anderson Toshiyuki Sasaki -Reviewed-by: Andreas Schneider ---- - tests/unittests/CMakeLists.txt | 3 + - tests/unittests/torture_packet_filter.c | 502 ++++++++++++++++++++++++++++++++ - 2 files changed, 505 insertions(+) - create mode 100644 tests/unittests/torture_packet_filter.c - -diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt -index 397ebd05..13887ff1 100644 ---- a/tests/unittests/CMakeLists.txt -+++ b/tests/unittests/CMakeLists.txt -@@ -35,6 +35,9 @@ target_compile_options(torture_knownhosts_parsing PRIVATE ${DEFAULT_C_COMPILE_FL - add_cmocka_test(torture_hashes torture_hashes.c ${TEST_TARGET_LIBRARIES}) - target_compile_options(torture_hashes PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) - -+add_cmocka_test(torture_packet_filter torture_packet_filter.c ${TORTURE_LIBRARY}) -+target_compile_options(torture_packet_filter PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) -+ - if (CMAKE_USE_PTHREADS_INIT) - add_cmocka_test(torture_rand torture_rand.c ${TEST_TARGET_LIBRARIES}) - target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) -diff --git a/tests/unittests/torture_packet_filter.c b/tests/unittests/torture_packet_filter.c -new file mode 100644 -index 00000000..72cbc4cd ---- /dev/null -+++ b/tests/unittests/torture_packet_filter.c -@@ -0,0 +1,502 @@ -+/* -+ * This file is part of the SSH Library -+ * -+ * Copyright (c) 2018 by Anderson Toshiyuki Sasaki -+ * -+ * The SSH 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. -+ * -+ * The SSH 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 the SSH Library; see the file COPYING. If not, write to -+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -+ * MA 02111-1307, USA. -+ */ -+ -+/* -+ * This test checks if the messages accepted by the packet filter were intented -+ * to be accepted. -+ * -+ * The process consists in 2 steps: -+ * - Try the filter with a message type in an arbitrary state -+ * - If the message is accepted by the filter, check if the message is in the -+ * set of accepted states. -+ * -+ * Only the values selected by the flag (COMPARE_*) are considered. -+ * */ -+ -+#include "config.h" -+ -+#define LIBSSH_STATIC -+ -+#include "torture.h" -+#include "libssh/priv.h" -+#include "libssh/libssh.h" -+#include "libssh/session.h" -+#include "libssh/auth.h" -+#include "libssh/ssh2.h" -+#include "libssh/packet.h" -+ -+#include "packet.c" -+ -+#define COMPARE_SESSION_STATE 1 -+#define COMPARE_ROLE (1 << 1) -+#define COMPARE_DH_STATE (1 << 2) -+#define COMPARE_AUTH_STATE (1 << 3) -+#define COMPARE_GLOBAL_REQ_STATE (1 << 4) -+#define COMPARE_CURRENT_METHOD (1 << 5) -+ -+#define SESSION_STATE_COUNT 11 -+#define DH_STATE_COUNT 4 -+#define AUTH_STATE_COUNT 15 -+#define GLOBAL_REQ_STATE_COUNT 5 -+#define MESSAGE_COUNT 100 // from 1 to 100 -+ -+#define ROLE_CLIENT 0 -+#define ROLE_SERVER 1 -+ -+/* -+ * This is the list of currently unfiltered message types. -+ * Only unrecognized types should be in this list. -+ * */ -+static uint8_t unfiltered[] = { -+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -+ 22, 23, 24, 25, 26, 27, 28, 29, -+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -+ 54, 55, 56, 57, 58, 59, -+ 62, -+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -+ 83, 84, 85, 86, 87, 88, 89, -+}; -+ -+typedef struct global_state_st { -+ /* If the bit in this flag is zero, the corresponding state is not -+ * considered, working as a wildcard (meaning any value is accepted) */ -+ uint32_t flags; -+ uint8_t role; -+ enum ssh_session_state_e session; -+ enum ssh_dh_state_e dh; -+ enum ssh_auth_state_e auth; -+ enum ssh_channel_request_state_e global_req; -+} global_state; -+ -+static int cmp_state(const void *e1, const void *e2) -+{ -+ global_state *s1 = (global_state *) e1; -+ global_state *s2 = (global_state *) e2; -+ -+ /* Compare role (client == 0 or server == 1)*/ -+ if (s1->role < s2->role) { -+ return -1; -+ } -+ else if (s1->role > s2->role) { -+ return 1; -+ } -+ -+ /* Compare session state */ -+ if (s1->session < s2->session) { -+ return -1; -+ } -+ else if (s1->session > s2->session) { -+ return 1; -+ } -+ -+ /* Compare DH state */ -+ if (s1->dh < s2->dh) { -+ return -1; -+ } -+ else if (s1->dh > s2->dh) { -+ return 1; -+ } -+ -+ /* Compare auth */ -+ if (s1->auth < s2->auth) { -+ return -1; -+ } -+ else if (s1->auth > s2->auth) { -+ return 1; -+ } -+ -+ /* Compare global_req */ -+ if (s1->global_req < s2->global_req) { -+ return -1; -+ } -+ else if (s1->global_req > s2->global_req) { -+ return 1; -+ } -+ -+ /* If all equal, they are equal */ -+ return 0; -+} -+ -+static int cmp_state_search(const void *key, const void *array_element) -+{ -+ global_state *s1 = (global_state *) key; -+ global_state *s2 = (global_state *) array_element; -+ -+ int result = 0; -+ -+ if (s2->flags & COMPARE_ROLE) { -+ /* Compare role (client == 0 or server == 1)*/ -+ if (s1->role < s2->role) { -+ return -1; -+ } -+ else if (s1->role > s2->role) { -+ return 1; -+ } -+ } -+ -+ if (s2->flags & COMPARE_SESSION_STATE) { -+ /* Compare session state */ -+ if (s1->session < s2->session) { -+ result = -1; -+ goto end; -+ } -+ else if (s1->session > s2->session) { -+ result = 1; -+ goto end; -+ } -+ } -+ -+ if (s2->flags & COMPARE_DH_STATE) { -+ /* Compare DH state */ -+ if (s1->dh < s2->dh) { -+ result = -1; -+ goto end; -+ } -+ else if (s1->dh > s2->dh) { -+ result = 1; -+ goto end; -+ } -+ } -+ -+ if (s2->flags & COMPARE_AUTH_STATE) { -+ /* Compare auth */ -+ if (s1->auth < s2->auth) { -+ result = -1; -+ goto end; -+ } -+ else if (s1->auth > s2->auth) { -+ result = 1; -+ goto end; -+ } -+ } -+ -+ if (s2->flags & COMPARE_GLOBAL_REQ_STATE) { -+ /* Compare global_req */ -+ if (s1->global_req < s2->global_req) { -+ result = -1; -+ goto end; -+ } -+ else if (s1->global_req > s2->global_req) { -+ result = 1; -+ goto end; -+ } -+ } -+ -+end: -+ return result; -+} -+ -+static int is_state_accepted(global_state *tested, global_state *accepted, -+ int accepted_len) -+{ -+ global_state *found = NULL; -+ -+ found = bsearch(tested, accepted, accepted_len, sizeof(global_state), -+ cmp_state_search); -+ -+ if (found != NULL) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int cmp_uint8(const void *i, const void *j) -+{ -+ uint8_t e1 = *((uint8_t *)i); -+ uint8_t e2 = *((uint8_t *)j); -+ -+ if (e1 < e2) { -+ return -1; -+ } -+ else if (e1 > e2) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int check_unfiltered(uint8_t msg_type) -+{ -+ uint8_t *found; -+ -+ found = bsearch(&msg_type, unfiltered, sizeof(unfiltered)/sizeof(uint8_t), -+ sizeof(uint8_t), cmp_uint8); -+ -+ if (found != NULL) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void torture_packet_filter_check_unfiltered(void **state) -+{ -+ ssh_session session; -+ -+ int role_c; -+ int auth_c; -+ int session_c; -+ int dh_c; -+ int global_req_c; -+ -+ uint8_t msg_type; -+ -+ enum ssh_packet_filter_result_e rc; -+ int in_unfiltered; -+ -+ session = ssh_new(); -+ -+ for (msg_type = 1; msg_type <= MESSAGE_COUNT; msg_type++) { -+ session->in_packet.type = msg_type; -+ for (role_c = 0; role_c < 2; role_c++) { -+ session->server = role_c; -+ for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) { -+ session->session_state = session_c; -+ for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) { -+ session->dh_handshake_state = dh_c; -+ for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) { -+ session->auth.state = auth_c; -+ for (global_req_c = 0; -+ global_req_c < GLOBAL_REQ_STATE_COUNT; -+ global_req_c++) -+ { -+ session->global_req_state = global_req_c; -+ -+ rc = ssh_packet_incoming_filter(session); -+ -+ if (rc == SSH_PACKET_UNKNOWN) { -+ in_unfiltered = check_unfiltered(msg_type); -+ -+ if (!in_unfiltered) { -+ fprintf(stderr, "Message type %d UNFILTERED " -+ "in state: role %d, session %d, dh %d, auth %d\n", -+ msg_type, role_c, session_c, dh_c, auth_c); -+ } -+ assert_int_equal(in_unfiltered, 1); -+ } -+ else { -+ in_unfiltered = check_unfiltered(msg_type); -+ -+ if (in_unfiltered) { -+ fprintf(stderr, "Message type %d NOT UNFILTERED " -+ "in state: role %d, session %d, dh %d, auth %d\n", -+ msg_type, role_c, session_c, dh_c, auth_c); -+ } -+ assert_int_equal(in_unfiltered, 0); -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ ssh_free(session); -+} -+ -+static int check_message_in_all_states(global_state accepted[], -+ int accepted_count, uint8_t msg_type) -+{ -+ ssh_session session; -+ -+ int role_c; -+ int auth_c; -+ int session_c; -+ int dh_c; -+ int global_req_c; -+ -+ enum ssh_packet_filter_result_e rc; -+ int in_accepted; -+ -+ global_state key; -+ -+ session = ssh_new(); -+ -+ /* Sort the accepted array so that the elements can be searched using -+ * bsearch */ -+ qsort(accepted, accepted_count, sizeof(global_state), cmp_state); -+ -+ session->in_packet.type = msg_type; -+ -+ for (role_c = 0; role_c < 2; role_c++) { -+ session->server = role_c; -+ key.role = role_c; -+ for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) { -+ session->session_state = session_c; -+ key.session = session_c; -+ for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) { -+ session->dh_handshake_state = dh_c; -+ key.dh = dh_c; -+ for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) { -+ session->auth.state = auth_c; -+ key.auth = auth_c; -+ for (global_req_c = 0; -+ global_req_c < GLOBAL_REQ_STATE_COUNT; -+ global_req_c++) -+ { -+ session->global_req_state = global_req_c; -+ key.global_req = global_req_c; -+ -+ rc = ssh_packet_incoming_filter(session); -+ -+ if (rc == SSH_PACKET_ALLOWED) { -+ in_accepted = is_state_accepted(&key, accepted, -+ accepted_count); -+ -+ if (!in_accepted) { -+ fprintf(stderr, "Message type %d ALLOWED " -+ "in state: role %d, session %d, dh %d, auth %d\n", -+ msg_type, role_c, session_c, dh_c, auth_c); -+ } -+ assert_int_equal(in_accepted, 1); -+ } -+ else if (rc == SSH_PACKET_DENIED) { -+ in_accepted = is_state_accepted(&key, accepted, accepted_count); -+ -+ if (in_accepted) { -+ fprintf(stderr, "Message type %d DENIED " -+ "in state: role %d, session %d, dh %d, auth %d\n", -+ msg_type, role_c, session_c, dh_c, auth_c); -+ } -+ assert_int_equal(in_accepted, 0); -+ } -+ else { -+ fprintf(stderr, "Message type %d UNFILTERED " -+ "in state: role %d, session %d, dh %d, auth %d\n", -+ msg_type, role_c, session_c, dh_c, auth_c); -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ ssh_free(session); -+ return 0; -+} -+ -+static void torture_packet_filter_check_auth_success(void **state) -+{ -+ int rc; -+ -+ global_state accepted[] = { -+ { -+ .flags = (COMPARE_SESSION_STATE | -+ COMPARE_ROLE | -+ COMPARE_AUTH_STATE | -+ COMPARE_DH_STATE), -+ .role = ROLE_CLIENT, -+ .session = SSH_SESSION_STATE_AUTHENTICATING, -+ .dh = DH_STATE_FINISHED, -+ .auth = SSH_AUTH_STATE_PUBKEY_AUTH_SENT, -+ }, -+ { -+ .flags = (COMPARE_SESSION_STATE | -+ COMPARE_ROLE | -+ COMPARE_AUTH_STATE | -+ COMPARE_DH_STATE), -+ .role = ROLE_CLIENT, -+ .session = SSH_SESSION_STATE_AUTHENTICATING, -+ .dh = DH_STATE_FINISHED, -+ .auth = SSH_AUTH_STATE_PASSWORD_AUTH_SENT, -+ }, -+ { -+ .flags = (COMPARE_SESSION_STATE | -+ COMPARE_ROLE | -+ COMPARE_AUTH_STATE | -+ COMPARE_DH_STATE), -+ .role = ROLE_CLIENT, -+ .session = SSH_SESSION_STATE_AUTHENTICATING, -+ .dh = DH_STATE_FINISHED, -+ .auth = SSH_AUTH_STATE_GSSAPI_MIC_SENT, -+ }, -+ { -+ .flags = (COMPARE_SESSION_STATE | -+ COMPARE_ROLE | -+ COMPARE_AUTH_STATE | -+ COMPARE_DH_STATE), -+ .role = ROLE_CLIENT, -+ .session = SSH_SESSION_STATE_AUTHENTICATING, -+ .dh = DH_STATE_FINISHED, -+ .auth = SSH_AUTH_STATE_KBDINT_SENT, -+ }, -+ { -+ .flags = (COMPARE_SESSION_STATE | -+ COMPARE_ROLE | -+ COMPARE_AUTH_STATE | -+ COMPARE_DH_STATE | -+ COMPARE_CURRENT_METHOD), -+ .role = ROLE_CLIENT, -+ .session = SSH_SESSION_STATE_AUTHENTICATING, -+ .dh = DH_STATE_FINISHED, -+ .auth = SSH_AUTH_STATE_AUTH_NONE_SENT, -+ } -+ }; -+ -+ int accepted_count = 5; -+ -+ /* Unused */ -+ (void) state; -+ -+ rc = check_message_in_all_states(accepted, accepted_count, -+ SSH2_MSG_USERAUTH_SUCCESS); -+ -+ assert_int_equal(rc, 0); -+} -+ -+static void torture_packet_filter_check_channel_open(void **state) -+{ -+ int rc; -+ -+ /* The only condition to accept a CHANNEL_OPEN is to be authenticated */ -+ global_state accepted[] = { -+ { -+ .flags = COMPARE_SESSION_STATE, -+ .session = SSH_SESSION_STATE_AUTHENTICATED, -+ } -+ }; -+ -+ int accepted_count = 1; -+ -+ /* Unused */ -+ (void) state; -+ -+ rc = check_message_in_all_states(accepted, accepted_count, -+ SSH2_MSG_CHANNEL_OPEN); -+ -+ assert_int_equal(rc, 0); -+} -+ -+int torture_run_tests(void) -+{ -+ int rc; -+ struct CMUnitTest tests[] = { -+ cmocka_unit_test(torture_packet_filter_check_auth_success), -+ cmocka_unit_test(torture_packet_filter_check_channel_open), -+ cmocka_unit_test(torture_packet_filter_check_unfiltered), -+ }; -+ -+ ssh_init(); -+ torture_filter_tests(tests); -+ rc = cmocka_run_group_tests(tests, NULL, NULL); -+ ssh_finalize(); -+ return rc; -+} --- -cgit v1.2.1 - diff --git a/libssh.keyring b/libssh.keyring deleted file mode 100644 index 411bf36750f0fc4a8856034415e39c7116559ee4..0000000000000000000000000000000000000000 Binary files a/libssh.keyring and /dev/null differ diff --git a/libssh.spec b/libssh.spec index 178725ab9b00dad4beb54c51b397a4cf14cf72cb..27bd3356a0d8c5910df6909c5e340347e296ab23 100644 --- a/libssh.spec +++ b/libssh.spec @@ -1,34 +1,21 @@ Name: libssh -Version: 0.8.3 -Release: 8 +Version: 0.9.4 +Release: 1 Summary: A library implementing the SSH protocol License: LGPLv2+ -URL: https://www.libssh.org -Source0: https://www.libssh.org/files/0.8/%{name}-%{version}.tar.xz -Source1: https://www.libssh.org/files/0.8/%{name}-%{version}.tar.xz.asc -Source2: https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D.gpg#/%{name}.keyring - -Patch1: libssh-0.8.3-fix-covscan-errors.patch -Patch2: libssh-0.8.3-fixes-the-oss-fuzz-bug.patch - -#patches6000-patches6007 come from https://git.libssh.org/ -Patch6000: libssh-stable-0p8-CVE-2018-10933-part1.patch -Patch6001: libssh-stable-0p8-CVE-2018-10933-part2.patch -Patch6002: libssh-stable-0p8-CVE-2018-10933-part3.patch -Patch6003: libssh-stable-0p8-CVE-2018-10933-part4.patch -Patch6004: libssh-stable-0p8-CVE-2018-10933-part5.patch -Patch6005: libssh-stable-0p8-CVE-2018-10933-part6.patch -Patch6006: libssh-stable-0p8-CVE-2018-10933-part7.patch -Patch6007: libssh-stable-0p8-CVE-2018-10933-part8.patch -Patch6008: 0001-CVE-2019-14889.patch -Patch6009: 0002-CVE-2019-14889.patch -Patch6010: 0003-CVE-2019-14889.patch -Patch6011: 0004-CVE-2019-14889.patch -Patch6012: 0005-CVE-2019-14889.patch -Patch6013: CVE-2020-1730.patch - -BuildRequires: cmake libcmocka-devel krb5-devel zlib-devel pkgconfig -BuildRequires: doxygen gcc-c++ gnupg2 openssl-devel +URL: http://www.libssh.org + +Source0: https://www.libssh.org/files/0.9/%{name}-%{version}.tar.xz +Source1: https://www.libssh.org/files/0.9/%{name}-%{version}.tar.xz.asc +Source2: https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D.gpg#/%{name}.keyring + +Patch1: libssh-0.9.4-fix-version.patch + +BuildRequires: cmake gcc-c++ gnupg2 openssl-devel pkgconfig zlib-devel +BuildRequires: krb5-devel libcmocka-devel openssh-clients openssh-server +BuildRequires: nmap-ncat + +Recommends: crypto-policies Provides: libssh_threads.so.4()(64bit) @@ -61,15 +48,15 @@ fi pushd obj %cmake .. \ - -DUNIT_TESTING=ON + -DUNIT_TESTING=ON \ %make_build VERBOSE=1 -make docs popd %install make DESTDIR=%{buildroot} install/fast -C obj +install -d -m755 %{buildroot}%{_sysconfdir}/libssh pushd %{buildroot}%{_libdir} for i in libssh.so*; @@ -100,19 +87,19 @@ popd %defattr(-,root,root) %{_includedir}/libssh/ %{_libdir}/cmake/libssh/ -%{_libdir}/pkgconfig/*.pc +%{_libdir}/pkgconfig/libssh.pc %{_libdir}/*.so %files help %defattr(-,root,root) -%doc README ChangeLog obj/doc/html +%doc ChangeLog README %changelog -* Fri Apr 17 2020 openEuler Buildteam - 0.8.3-8 -- Type:cves -- ID:CVE-2020-1730 +* Mon Apr 20 2020 openEuler Buildteam - 0.9.4-1 +- Type:bugfix +- Id:NA - SUG:NA -- DESC:fix CVE-2020-1730 +- DESC:update to 0.9.4 * Sun Jan 12 2020 openEuler Buildteam - 0.8.3-7 - Type:bugfix