File CVE-2019-14889.patch of Package libssh

From 4aea835974996b2deb011024c53f4ff4329a95b5 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 31 Oct 2019 17:56:34 +0100
Subject: [PATCH 1/7] CVE-2019-14889: scp: Reformat scp.c

Fixes T181

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 42c727d0c186a1e2fa84a31ab40e16e58b404ab3)
---

---
From 82c375b7c99141a5495e62060e0b7f9c97981e7e Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Fri, 25 Oct 2019 13:24:28 +0200
Subject: [PATCH 2/7] 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 <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c75d417d06867fd792b788e6281334621c2cd335)
---

---
From 2ba1dea5493fb2f5a5be2dd263ce46ccb5f8ec76 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Tue, 22 Oct 2019 16:08:24 +0200
Subject: [PATCH 3/7] 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 <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c4ad1aba9860e02fe03ef3f58a047964e9e765fc)
---

---
From 391c78de9d0f7baec3a44d86a76f4e1324eb9529 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@cryptomilk.org>
Date: Fri, 6 Dec 2019 09:40:30 +0100
Subject: [PATCH 4/7] CVE-2019-14889: scp: Don't allow file path longer than
 32kb

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit 0b5ee397260b6e08dffa2c1ce515a153aaeda765)
---

---
From b0edec4e8d01ad73b0d26ad4070d7e1a1e86dfc8 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 31 Oct 2019 18:10:27 +0100
Subject: [PATCH 5/7] 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 <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 3830c7ae6eec751b7618d3fc159cb5bb3c8806a6)
---

---
From 30c0f0c0e3a87c1c0ee42d3dc3f77cbcab89f767 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@cryptomilk.org>
Date: Mon, 9 Dec 2019 19:20:43 +0100
Subject: [PATCH 6/7] cpack: Ignore patch files and other stuff

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
(cherry picked from commit ecc78ec154763b96b06fc6c00eb039d0c6c96a3d)
---

Index: libssh-0.8.7/src/scp.c
===================================================================
--- libssh-0.8.7.orig/src/scp.c
+++ libssh-0.8.7/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
@@ -57,30 +58,53 @@
  *
  * @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;
+    }
+
+    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,
+                      "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 +118,115 @@ ssh_scp ssh_scp_new(ssh_session session,
  */
 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};
+    char *quoted_location = NULL;
+    size_t quoted_location_len = 0;
+    size_t scp_location_len;
+
+    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;
+    }
+
+    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->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" : "", quoted_location);
+    } else {
+        snprintf(execbuffer, sizeof(execbuffer), "scp -f %s %s",
+                scp->recursive ? "-r" : "", quoted_location);
+    }
+
+    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;
+    }
+
+    if (scp->mode == SSH_SCP_WRITE) {
+        rc = ssh_scp_response(scp, NULL);
+        if (rc != 0) {
+            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 +240,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;
-    }
-    ssh_channel_free(scp->channel);
-    scp->channel=NULL;
-  }
-  scp->state=SSH_SCP_NEW;
-  return SSH_OK;
+
+    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;
+    }
+
+    scp->state = SSH_SCP_NEW;
+    return SSH_OK;
 }
 
 /**
@@ -198,16 +285,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 +317,83 @@ 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;
+    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_scp_response(scp, NULL);
+    if (rc != 0) {
+        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;
+
+    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_scp_response(scp, NULL);
+    if (rc != 0) {
+        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 +409,49 @@ int ssh_scp_push_directory(ssh_scp scp,
  *
  * @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;
+
+    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_scp_response(scp, NULL);
+    if (rc != 0) {
+        return SSH_ERROR;
+    }
+
+    scp->filelen = size;
+    scp->processed = 0;
+    scp->state = SSH_SCP_WRITE_WRITING;
+
+    return SSH_OK;
 }
 
 /**
@@ -369,8 +469,9 @@ int ssh_scp_push_file64(ssh_scp scp, con
  * @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 +486,60 @@ int ssh_scp_push_file(ssh_scp scp, const
  *
  * @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 %u 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 +554,66 @@ int ssh_scp_response(ssh_scp scp, char *
  * @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_scp_response(scp, NULL);
+        if (rc != 0) {
+            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 +630,36 @@ int ssh_scp_write(ssh_scp scp, const voi
  * @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(r<len-1){
-    err=ssh_channel_read(scp->channel,&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 +682,105 @@ int ssh_scp_read_string(ssh_scp scp, cha
  * @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 +794,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 +830,32 @@ int ssh_scp_deny_request(ssh_scp scp, co
  * @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 +868,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;
+int ssh_scp_read(ssh_scp scp, void *buffer, size_t size)
+{
+    int rc;
+    int code;
+
+    if (scp == NULL) {
+        return SSH_ERROR;
     }
-    scp->state=SSH_SCP_ERROR;
-    return SSH_ERROR;
-  }
-  return r;
+
+    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 +935,13 @@ int ssh_scp_read(ssh_scp scp, void *buff
  * @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 +950,13 @@ const char *ssh_scp_request_get_filename
  *
  * @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 +966,24 @@ int ssh_scp_request_get_permissions(ssh_
  *                      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 +993,10 @@ uint64_t ssh_scp_request_get_size64(ssh_
  *
  * @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 +1007,11 @@ int ssh_scp_integer_mode(const char *mod
  * @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 +1022,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;
 }
 
 /** @} */
Index: libssh-0.8.7/CPackConfig.cmake
===================================================================
--- libssh-0.8.7.orig/CPackConfig.cmake
+++ libssh-0.8.7/CPackConfig.cmake
@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERS
 
 # SOURCE GENERATOR
 set(CPACK_SOURCE_GENERATOR "TXZ")
-set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
+set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
 set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
 
 ### NSIS INSTALLER
Index: libssh-0.8.7/include/libssh/misc.h
===================================================================
--- libssh-0.8.7.orig/include/libssh/misc.h
+++ libssh-0.8.7/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_timest
 
 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_ */
Index: libssh-0.8.7/src/misc.c
===================================================================
--- libssh-0.8.7.orig/src/misc.c
+++ libssh-0.8.7/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;
+}
+
 /** @} */
openSUSE Build Service is sponsored by