aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorAnderson Toshiyuki Sasaki <ansasaki@redhat.com>2018-09-25 16:08:30 +0200
committerAndreas Schneider <asn@cryptomilk.org>2018-09-27 15:21:30 +0200
commit00e5ef1b3c3895a60a48d735829879282b6b1f60 (patch)
treee9d0f8ebca5c85121cd074193f5674c87afa6b71 /examples
parent6eef4b4a3c32f01532b241f690e8a276d92c2ca4 (diff)
downloadlibssh-00e5ef1b3c3895a60a48d735829879282b6b1f60.tar.gz
libssh-00e5ef1b3c3895a60a48d735829879282b6b1f60.tar.xz
libssh-00e5ef1b3c3895a60a48d735829879282b6b1f60.zip
examples: Fix possible memory leak in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'examples')
-rw-r--r--examples/libssh_scp.c109
1 files changed, 89 insertions, 20 deletions
diff --git a/examples/libssh_scp.c b/examples/libssh_scp.c
index 46199f47..51413e9f 100644
--- a/examples/libssh_scp.c
+++ b/examples/libssh_scp.c
@@ -83,6 +83,31 @@ static int opts(int argc, char **argv){
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);
+ }
+}
+
static struct location *parse_location(char *loc){
struct location *location;
char *ptr;
@@ -114,6 +139,35 @@ static struct location *parse_location(char *loc){
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;
+ }
+ }
+ }
+}
+
static int open_location(struct location *loc, int flag){
if(loc->is_ssh && flag==WRITE){
loc->session=connect_ssh(loc->host,loc->user,verbosity);
@@ -124,12 +178,18 @@ static int open_location(struct location *loc, int flag){
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;
@@ -142,12 +202,18 @@ static int open_location(struct location *loc, int flag){
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;
@@ -296,33 +362,36 @@ int main(int argc, char **argv){
struct location *dest, *src;
int i;
int r;
- if(opts(argc,argv)<0)
- return EXIT_FAILURE;
+ if(opts(argc,argv)<0) {
+ r = EXIT_FAILURE;
+ goto end;
+ }
dest=parse_location(destination);
- if(open_location(dest,WRITE)<0)
- return EXIT_FAILURE;
+ if(open_location(dest,WRITE)<0) {
+ location_free(dest);
+ r = EXIT_FAILURE;
+ goto end;
+ }
for(i=0;i<nsources;++i){
src=parse_location(sources[i]);
if(open_location(src,READ)<0){
- return EXIT_FAILURE;
+ 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);
}
- if (dest->is_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;
+ r = 0;
+
+close_dest:
+ close_location(dest);
+ location_free(dest);
+end:
+ return r;
}