diff options
-rw-r--r-- | src/file.c | 71 | ||||
-rw-r--r-- | src/file.h | 12 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/ssh.c | 9 |
4 files changed, 58 insertions, 40 deletions
@@ -135,7 +135,7 @@ int file_directory_exists(char *path, sftp_session sftp) return ret; } -static struct file *file_alloc(char *path, size_t size, bool remote) +static struct file *file_alloc(char *src_path, size_t size, bool src_is_remote) { struct file *f; @@ -146,16 +146,16 @@ static struct file *file_alloc(char *path, size_t size, bool remote) } memset(f, 0, sizeof(*f)); - strncpy(f->path, path, PATH_MAX - 1); + strncpy(f->src_path, src_path, PATH_MAX - 1); f->size = size; - f->remote = remote; - f->dst_remote = !remote; + f->src_is_remote = src_is_remote; + f->dst_is_remote = !src_is_remote; lock_init(&f->lock); return f; } -static bool file_should_skip(char *path) +static bool check_file_should_skip(char *path) { int len = strlen(path); if ((len == 1 && strncmp(path, ".", 1) == 0) || @@ -203,6 +203,15 @@ static int check_file_tobe_copied(char *path, sftp_session sftp, size_t *size) return ret; } +static int check_pathlen(const char *src, const char *dst) +{ + if ((strlen(src) + strlen(dst) + 1) > PATH_MAX) { + pr_err("too long path: %s/%s\n", src, dst); + return -1; + } + return 0; +} + static int file_fill_recursive(struct list_head *file_list, bool dst_is_remote, sftp_session sftp, char *src_path, char *rel_path, char *dst_path, bool dst_should_dir) @@ -235,9 +244,9 @@ static int file_fill_recursive(struct list_head *file_list, snprintf(f->dst_path, PATH_MAX, "%s%s", rel_path, dst_path); list_add_tail(&f->list, file_list); - pprint2("file %s %s -> %s %s\n", - f->path, dst_is_remote ? "(local)" : "(remote)", - f->dst_path, dst_is_remote ? "(remote)" : "(local)"); + pprint2("file %s %s -> %s %s %luB\n", + f->src_path, strloc(f->src_is_remote), + f->dst_path, strloc(f->dst_is_remote), f->size); return 0; } @@ -252,8 +261,11 @@ static int file_fill_recursive(struct list_head *file_list, return -1; } while ((de = readdir(dir)) != NULL) { - if (file_should_skip(de->d_name)) + if (check_file_should_skip(de->d_name)) continue; + if (check_pathlen(src_path, de->d_name) < 0 || + check_pathlen(rel_path, basename(src_path)) < 0) + return -1; snprintf(next_src_path, sizeof(next_src_path), "%s/%s", src_path, de->d_name); snprintf(next_rel_path, sizeof(next_rel_path), @@ -274,8 +286,11 @@ static int file_fill_recursive(struct list_head *file_list, return -1; } while ((attr = sftp_readdir(sftp, dir)) != NULL) { - if (file_should_skip(attr->name)) + if (check_file_should_skip(attr->name)) continue; + if (check_pathlen(src_path, attr->name) < 0 || + check_pathlen(rel_path, basename(src_path)) < 0) + return -1; snprintf(next_src_path, sizeof(next_src_path), "%s/%s", src_path, attr->name); snprintf(next_rel_path, sizeof(next_rel_path), @@ -380,8 +395,8 @@ void file_dump(struct list_head *file_list) list_for_each_entry(f, file_list, list) { pr_debug("%s %s -> %s %s %lu-byte\n", - f->path, f->remote ? "(remote)" : "(local)", - f->dst_path, f->dst_remote ? "(remote)" : "(local)", + f->src_path, strloc(f->src_is_remote), + f->dst_path, strloc(f->dst_is_remote), f->size); } } @@ -443,7 +458,7 @@ int chunk_fill(struct list_head *file_list, struct list_head *chunk_list, chunk_sz = min_chunk_sz; } - pr_debug("%s chunk_sz %lu-byte\n", f->path, chunk_sz); + pr_debug("%s chunk_sz %lu-byte\n", f->src_path, chunk_sz); for (size = f->size; size > 0;) { c = chunk_alloc(f); @@ -454,7 +469,7 @@ int chunk_fill(struct list_head *file_list, struct list_head *chunk_list, size -= c->len; list_add_tail(&c->list, chunk_list); pprint4("chunk %s 0x%010lx-0x%010lx %luB\n", - c->f->path, c->off, c->off + c->len, c->len); + c->f->src_path, c->off, c->off + c->len, c->len); } } @@ -468,7 +483,7 @@ void chunk_dump(struct list_head *chunk_list) list_for_each_entry(c, chunk_list, list) { pr_debug("%s %s 0x%010lx-0x%010lx %lu-byte\n", - c->f->path, c->f->remote ? "(remote)" : "(local)", + c->f->src_path, strloc(f->src_is_remote), c->off, c->off + c->len, c->len); } } @@ -497,12 +512,12 @@ int chunk_prepare(struct chunk *c, sftp_session sftp) lock_acquire(&f->lock); /* XXX: is always acquiring lock per-chunk heavy? */ if (f->state == FILE_STATE_INIT) { - if (file_dst_prepare(f, f->dst_remote ? sftp : NULL) < 0) { + if (file_dst_prepare(f, f->dst_is_remote ? sftp : NULL) < 0) { ret = -1; goto out; } f->state = FILE_STATE_OPENED; - pprint2("copy start: %s\n", f->path); + pprint2("copy start: %s\n", f->src_path); } out: @@ -649,7 +664,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp, flags = O_RDONLY; mode = S_IRUSR; - if ((fd = chunk_open_local(f->path, flags, mode, c->off)) < 0) { + if ((fd = chunk_open_local(f->src_path, flags, mode, c->off)) < 0) { ret = -1; goto out; } @@ -665,7 +680,7 @@ static int chunk_copy_local_to_remote(struct chunk *c, sftp_session sftp, if (ret < 0) goto out; - if ((mode = chunk_get_mode(f->path, NULL)) < 0) { + if ((mode = chunk_get_mode(f->src_path, NULL)) < 0) { ret = -1; goto out; } @@ -701,7 +716,7 @@ static int chunk_copy_remote_to_local(struct chunk *c, sftp_session sftp, flags = O_RDONLY; mode = S_IRUSR; - if (!(sf = chunk_open_remote(f->path, flags, mode, c->off, sftp))) { + if (!(sf = chunk_open_remote(f->src_path, flags, mode, c->off, sftp))) { ret = -1; goto out; } @@ -728,14 +743,14 @@ int chunk_copy(struct chunk *c, sftp_session sftp, size_t sftp_buf_sz, size_t io int ret = 0; pr_debug("copy %s %s -> %s %s off=0x%010lx\n", - f->path, f->remote ? "(remote)" : "(local)", - f->dst_path, f->dst_remote ? "(remote)" : "(local)", c->off); + f->src_path, strloc(f->src_is_remote), + f->dst_path, strloc(f->dst_is_remote), c->off); pprint4("copy start: chunk %s 0x%010lx-0x%010lx %luB\n", - c->f->path, c->off, c->off + c->len, c->len); + c->f->src_path, c->off, c->off + c->len, c->len); - if (f->dst_remote) + if (f->dst_is_remote) ret = chunk_copy_local_to_remote(c, sftp, sftp_buf_sz, io_buf_sz, counter); else @@ -746,15 +761,15 @@ int chunk_copy(struct chunk *c, sftp_session sftp, size_t sftp_buf_sz, size_t io return ret; pr_debug("done %s %s -> %s %s off=0x%010lx\n", - f->path, f->remote ? "(remote)" : "(local)", - f->dst_path, f->dst_remote ? "(remote)" : "(local)", c->off); + f->src_path, strloc(f->src_is_remote), + f->dst_path, strloc(f->dst_is_remote), c->off); pprint4("copy done: chunk %s 0x%010lx-0x%010lx %luB\n", - c->f->path, c->off, c->off + c->len, c->len); + c->f->src_path, c->off, c->off + c->len, c->len); if (refcnt_dec(&f->refcnt) == 0) { f->state = FILE_STATE_DONE; - pprint2("copy done: %s\n", f->path); + pprint2("copy done: %s\n", f->src_path); } @@ -12,12 +12,12 @@ struct file { struct list_head list; /* sscp->file_list */ - char path[PATH_MAX]; /* copy source path */ - bool remote; /* source is remote */ - size_t size; /* size of this file */ + char src_path[PATH_MAX]; /* copy source path */ + bool src_is_remote; /* source is remote */ + size_t size; /* size of this file */ - char dst_path[PATH_MAX]; /* copy destination path */ - bool dst_remote; /* destination is remote */ + char dst_path[PATH_MAX]; /* copy destination path */ + bool dst_is_remote; /* destination is remote */ int state; /* destination file state */ lock lock; /* mutex to protect state */ @@ -27,6 +27,8 @@ struct file { #define FILE_STATE_OPENED 1 #define FILE_STATE_DONE 2 +#define strloc(is_remote) is_remote ? "(remote)" : "(local)" + /* Allocating chunk increments refcnt of the associating file. * Multiple threads copying files follows: * @@ -425,9 +425,9 @@ static void print_progress_bar(double percent, char *suffix) struct winsize ws; char buf[128]; -/* - * [=======> ] XX.X% SUFFIX - */ + /* + * [=======> ] XX.X% SUFFIX + */ buf[0] = '\0'; @@ -55,7 +55,7 @@ static int ssh_authenticate(ssh_session ssh, struct ssh_opts *opts) int auth_bit_mask; int ret; -/* none method */ + /* none method */ ret = ssh_userauth_none(ssh, NULL); if (ret == SSH_AUTH_SUCCESS) return 0; @@ -178,12 +178,12 @@ static int ssh_verify_known_hosts(ssh_session session) state = ssh_session_is_known_server(session); switch (state) { case SSH_KNOWN_HOSTS_OK: -/* OK */ + /* OK */ break; case SSH_KNOWN_HOSTS_CHANGED: fprintf(stderr, "Host key for server changed: it is now:\n"); -//ssh_print_hexa("Public key hash", hash, hlen); + //ssh_print_hexa("Public key hash", hash, hlen); fprintf(stderr, "For security reasons, connection will be stopped\n"); ssh_clean_pubkey_hash(&hash); @@ -201,12 +201,13 @@ static int ssh_verify_known_hosts(ssh_session session) fprintf(stderr, "If you accept the host key here, the file will be" "automatically created.\n"); -/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */ + /* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */ case SSH_KNOWN_HOSTS_UNKNOWN: hexa = ssh_get_hexa(hash, hlen); fprintf(stderr,"The server is unknown. Do you trust the host key?\n"); fprintf(stderr, "Public key hash: %s\n", hexa); + fprintf(stderr, "(yes/no): "); ssh_string_free_char(hexa); ssh_clean_pubkey_hash(&hash); p = fgets(buf, sizeof(buf), stdin); |