version 1.136, 2020/05/15 03:57:33 |
version 1.137, 2020/10/18 11:32:02 |
|
|
int r; |
int r; |
|
|
if ((r = sshbuf_reserve(m, 4, &p)) != 0) |
if ((r = sshbuf_reserve(m, 4, &p)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "reserve"); |
if (atomicio6(read, conn->fd_in, p, 4, sftpio, |
if (atomicio6(read, conn->fd_in, p, 4, sftpio, |
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) { |
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) { |
if (errno == EPIPE || errno == ECONNRESET) |
if (errno == EPIPE || errno == ECONNRESET) |
|
|
} |
} |
|
|
if ((r = sshbuf_get_u32(m, &msg_len)) != 0) |
if ((r = sshbuf_get_u32(m, &msg_len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "sshbuf_get_u32"); |
if (msg_len > SFTP_MAX_MSG_LENGTH) { |
if (msg_len > SFTP_MAX_MSG_LENGTH) { |
do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL, |
do_log2(initial ? SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_FATAL, |
"Received message too long %u", msg_len); |
"Received message too long %u", msg_len); |
|
|
} |
} |
|
|
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) |
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "reserve"); |
if (atomicio6(read, conn->fd_in, p, msg_len, sftpio, |
if (atomicio6(read, conn->fd_in, p, msg_len, sftpio, |
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) |
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) |
!= msg_len) { |
!= msg_len) { |
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, code)) != 0 || |
if ((r = sshbuf_put_u8(msg, code)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_string(msg, s, len)) != 0) |
(r = sshbuf_put_string(msg, s, len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); |
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, code)) != 0 || |
if ((r = sshbuf_put_u8(msg, code)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_string(msg, s, len)) != 0 || |
(r = sshbuf_put_string(msg, s, len)) != 0 || |
(r = encode_attrib(msg, a)) != 0) |
(r = encode_attrib(msg, a)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); |
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%u != %u)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
SSH2_FXP_STATUS, type); |
SSH2_FXP_STATUS, type); |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
debug3("SSH2_FXP_STATUS %u", status); |
debug3("SSH2_FXP_STATUS %u", status); |
|
|
va_end(args); |
va_end(args); |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("%s: ID mismatch (%u != %u)", |
fatal("%s: ID mismatch (%u != %u)", |
errfmt == NULL ? __func__ : errmsg, id, expected_id); |
errfmt == NULL ? __func__ : errmsg, id, expected_id); |
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse status"); |
if (errfmt != NULL) |
if (errfmt != NULL) |
error("%s: %s", errmsg, fx2txt(status)); |
error("%s: %s", errmsg, fx2txt(status)); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); |
errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); |
|
|
if ((r = sshbuf_get_string(msg, &handle, len)) != 0) |
if ((r = sshbuf_get_string(msg, &handle, len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse handle"); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
return handle; |
return handle; |
|
|
static Attrib a; |
static Attrib a; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
get_msg(conn, msg); |
get_msg(conn, msg); |
|
|
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
debug3("Received stat reply T:%u I:%u", type, id); |
debug3("Received stat reply T:%u I:%u", type, id); |
if (id != expected_id) |
if (id != expected_id) |
|
|
u_int status; |
u_int status; |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse status"); |
if (quiet) |
if (quiet) |
debug("Couldn't stat remote file: %s", fx2txt(status)); |
debug("Couldn't stat remote file: %s", fx2txt(status)); |
else |
else |
|
|
SSH2_FXP_ATTRS, type); |
SSH2_FXP_ATTRS, type); |
} |
} |
if ((r = decode_attrib(msg, &a)) != 0) { |
if ((r = decode_attrib(msg, &a)) != 0) { |
error("%s: couldn't decode attrib: %s", __func__, ssh_err(r)); |
error_fr(r, "decode_attrib"); |
sshbuf_free(msg); |
sshbuf_free(msg); |
return NULL; |
return NULL; |
} |
} |
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
get_msg(conn, msg); |
get_msg(conn, msg); |
|
|
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
debug3("Received statvfs reply T:%u I:%u", type, id); |
debug3("Received statvfs reply T:%u I:%u", type, id); |
if (id != expected_id) |
if (id != expected_id) |
|
|
u_int status; |
u_int status; |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse status"); |
if (quiet) |
if (quiet) |
debug("Couldn't statvfs: %s", fx2txt(status)); |
debug("Couldn't statvfs: %s", fx2txt(status)); |
else |
else |
|
|
(r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 || |
(r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 || |
(r = sshbuf_get_u64(msg, &flag)) != 0 || |
(r = sshbuf_get_u64(msg, &flag)) != 0 || |
(r = sshbuf_get_u64(msg, &st->f_namemax)) != 0) |
(r = sshbuf_get_u64(msg, &st->f_namemax)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse statvfs"); |
|
|
st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; |
st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; |
st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; |
st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; |
|
|
ret->limit_kbps = 0; |
ret->limit_kbps = 0; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 || |
(r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0) |
(r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
send_msg(ret, msg); |
send_msg(ret, msg); |
|
|
sshbuf_reset(msg); |
sshbuf_reset(msg); |
|
|
|
|
/* Expecting a VERSION reply */ |
/* Expecting a VERSION reply */ |
if ((r = sshbuf_get_u8(msg, &type)) != 0) |
if ((r = sshbuf_get_u8(msg, &type)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse type"); |
if (type != SSH2_FXP_VERSION) { |
if (type != SSH2_FXP_VERSION) { |
error("Invalid packet back from SSH2_FXP_INIT (type %u)", |
error("Invalid packet back from SSH2_FXP_INIT (type %u)", |
type); |
type); |
|
|
return(NULL); |
return(NULL); |
} |
} |
if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) |
if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse version"); |
|
|
debug2("Remote version: %u", ret->version); |
debug2("Remote version: %u", ret->version); |
|
|
|
|
|
|
if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 || |
if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 || |
(r = sshbuf_get_string(msg, &value, &vlen)) != 0) |
(r = sshbuf_get_string(msg, &value, &vlen)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse extension"); |
if (strcmp(name, "posix-rename@openssh.com") == 0 && |
if (strcmp(name, "posix-rename@openssh.com") == 0 && |
strcmp((char *)value, "1") == 0) { |
strcmp((char *)value, "1") == 0) { |
ret->exts |= SFTP_EXT_POSIX_RENAME; |
ret->exts |= SFTP_EXT_POSIX_RENAME; |
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
id = conn->msg_id++; |
id = conn->msg_id++; |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message SSH2_FXP_CLOSE I:%u", id); |
debug3("Sent message SSH2_FXP_CLOSE I:%u", id); |
|
|
|
|
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, path)) != 0) |
(r = sshbuf_put_cstring(msg, path)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose OPENDIR"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
|
|
handle = get_handle(conn, id, &handle_len, |
handle = get_handle(conn, id, &handle_len, |
|
|
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose READDIR"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
|
|
sshbuf_reset(msg); |
sshbuf_reset(msg); |
|
|
|
|
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
debug3("Received reply T:%u I:%u", type, id); |
debug3("Received reply T:%u I:%u", type, id); |
|
|
|
|
u_int rstatus; |
u_int rstatus; |
|
|
if ((r = sshbuf_get_u32(msg, &rstatus)) != 0) |
if ((r = sshbuf_get_u32(msg, &rstatus)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse status"); |
__func__, ssh_err(r)); |
|
debug3("Received SSH2_FXP_STATUS %d", rstatus); |
debug3("Received SSH2_FXP_STATUS %d", rstatus); |
if (rstatus == SSH2_FX_EOF) |
if (rstatus == SSH2_FX_EOF) |
break; |
break; |
|
|
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse count"); |
if (count > SSHBUF_SIZE_MAX) |
if (count > SSHBUF_SIZE_MAX) |
fatal("%s: nonsensical number of entries", __func__); |
fatal_f("nonsensical number of entries"); |
if (count == 0) |
if (count == 0) |
break; |
break; |
debug3("Received %d SSH2_FXP_NAME responses", count); |
debug3("Received %d SSH2_FXP_NAME responses", count); |
|
|
NULL)) != 0 || |
NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, |
(r = sshbuf_get_cstring(msg, &longname, |
NULL)) != 0) |
NULL)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse filenames"); |
__func__, ssh_err(r)); |
|
if ((r = decode_attrib(msg, &a)) != 0) { |
if ((r = decode_attrib(msg, &a)) != 0) { |
error("%s: couldn't decode attrib: %s", |
error_fr(r, "couldn't decode attrib"); |
__func__, ssh_err(r)); |
|
free(filename); |
free(filename); |
free(longname); |
free(longname); |
goto out; |
goto out; |
|
|
strlen(path)); |
strlen(path)); |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%u != %u)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
u_int status; |
u_int status; |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse status"); |
error("Couldn't canonicalize: %s", fx2txt(status)); |
error("Couldn't canonicalize: %s", fx2txt(status)); |
sshbuf_free(msg); |
sshbuf_free(msg); |
return NULL; |
return NULL; |
|
|
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse count"); |
if (count != 1) |
if (count != 1) |
fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); |
fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); |
|
|
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = decode_attrib(msg, &a)) != 0) |
(r = decode_attrib(msg, &a)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse filename/attrib"); |
|
|
debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, |
debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, |
(unsigned long)a.size); |
(unsigned long)a.size); |
|
|
int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; |
int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
/* Send rename request */ |
/* Send rename request */ |
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, |
(r = sshbuf_put_cstring(msg, |
"posix-rename@openssh.com")) != 0) |
"posix-rename@openssh.com")) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose posix-rename"); |
} else { |
} else { |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0) |
(r = sshbuf_put_u32(msg, id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose rename"); |
} |
} |
if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose paths"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message %s \"%s\" -> \"%s\"", |
debug3("Sent message %s \"%s\" -> \"%s\"", |
use_ext ? "posix-rename@openssh.com" : |
use_ext ? "posix-rename@openssh.com" : |
|
|
} |
} |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
/* Send link request */ |
/* Send link request */ |
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
(r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
(r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", |
debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", |
oldpath, newpath); |
oldpath, newpath); |
|
|
} |
} |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
/* Send symlink request */ |
/* Send symlink request */ |
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
(r = sshbuf_put_cstring(msg, oldpath)) != 0 || |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
(r = sshbuf_put_cstring(msg, newpath)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, |
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, |
newpath); |
newpath); |
|
|
|
|
/* Send fsync request */ |
/* Send fsync request */ |
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
id = conn->msg_id++; |
id = conn->msg_id++; |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message fsync@openssh.com I:%u", id); |
debug3("Sent message fsync@openssh.com I:%u", id); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); |
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%u != %u)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
u_int status; |
u_int status; |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse status"); |
error("Couldn't readlink: %s", fx2txt(status)); |
error("Couldn't readlink: %s", fx2txt(status)); |
sshbuf_free(msg); |
sshbuf_free(msg); |
return(NULL); |
return(NULL); |
|
|
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
if ((r = sshbuf_get_u32(msg, &count)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse count"); |
if (count != 1) |
if (count != 1) |
fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); |
fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); |
|
|
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || |
(r = decode_attrib(msg, &a)) != 0) |
(r = decode_attrib(msg, &a)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse filenames/attrib"); |
|
|
debug3("SSH_FXP_READLINK %s -> %s", path, filename); |
debug3("SSH_FXP_READLINK %s -> %s", path, filename); |
|
|
|
|
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, path)) != 0) |
(r = sshbuf_put_cstring(msg, path)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
|
|
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
|
|
|
|
id = conn->msg_id++; |
id = conn->msg_id++; |
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 || |
(r = sshbuf_put_cstring(msg, path)) != 0 || |
(r = sshbuf_put_cstring(msg, path)) != 0 || |
(r = encode_attrib(msg, a)) != 0) |
(r = encode_attrib(msg, a)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|
|
|
int r; |
int r; |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_u32(msg, id)) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0 || |
(r = sshbuf_put_string(msg, handle, handle_len)) != 0 || |
(r = sshbuf_put_u64(msg, offset)) != 0 || |
(r = sshbuf_put_u64(msg, offset)) != 0 || |
(r = sshbuf_put_u32(msg, len)) != 0) |
(r = sshbuf_put_u32(msg, len)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
sshbuf_free(msg); |
sshbuf_free(msg); |
} |
} |
|
|
|
|
buflen = conn->transfer_buflen; |
buflen = conn->transfer_buflen; |
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
attrib_clear(&junk); /* Send empty attributes */ |
attrib_clear(&junk); /* Send empty attributes */ |
|
|
|
|
(r = sshbuf_put_cstring(msg, remote_path)) != 0 || |
(r = sshbuf_put_cstring(msg, remote_path)) != 0 || |
(r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || |
(r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || |
(r = encode_attrib(msg, &junk)) != 0) |
(r = encode_attrib(msg, &junk)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
|
|
|
|
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &id)) != 0) |
(r = sshbuf_get_u32(msg, &id)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "parse"); |
debug3("Received reply T:%u I:%u R:%d", type, id, max_req); |
debug3("Received reply T:%u I:%u R:%d", type, id, max_req); |
|
|
/* Find the request in our queue */ |
/* Find the request in our queue */ |
|
|
switch (type) { |
switch (type) { |
case SSH2_FXP_STATUS: |
case SSH2_FXP_STATUS: |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse status"); |
__func__, ssh_err(r)); |
|
if (status != SSH2_FX_EOF) |
if (status != SSH2_FX_EOF) |
read_error = 1; |
read_error = 1; |
max_req = 0; |
max_req = 0; |
|
|
break; |
break; |
case SSH2_FXP_DATA: |
case SSH2_FXP_DATA: |
if ((r = sshbuf_get_string(msg, &data, &len)) != 0) |
if ((r = sshbuf_get_string(msg, &data, &len)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse data"); |
__func__, ssh_err(r)); |
|
debug3("Received data %llu -> %llu", |
debug3("Received data %llu -> %llu", |
(unsigned long long)req->offset, |
(unsigned long long)req->offset, |
(unsigned long long)req->offset + len - 1); |
(unsigned long long)req->offset + len - 1); |
|
|
} |
} |
|
|
if ((msg = sshbuf_new()) == NULL) |
if ((msg = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal_f("sshbuf_new failed"); |
|
|
/* Send open request */ |
/* Send open request */ |
id = conn->msg_id++; |
id = conn->msg_id++; |
|
|
(r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| |
(r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| |
(resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 || |
(resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 || |
(r = encode_attrib(msg, &a)) != 0) |
(r = encode_attrib(msg, &a)) != 0) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal_fr(r, "compose"); |
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
|
|
|
|
handle_len)) != 0 || |
handle_len)) != 0 || |
(r = sshbuf_put_u64(msg, offset)) != 0 || |
(r = sshbuf_put_u64(msg, offset)) != 0 || |
(r = sshbuf_put_string(msg, data, len)) != 0) |
(r = sshbuf_put_string(msg, data, len)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "compose"); |
__func__, ssh_err(r)); |
|
send_msg(conn, msg); |
send_msg(conn, msg); |
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", |
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", |
id, (unsigned long long)offset, len); |
id, (unsigned long long)offset, len); |
|
|
get_msg(conn, msg); |
get_msg(conn, msg); |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
if ((r = sshbuf_get_u8(msg, &type)) != 0 || |
(r = sshbuf_get_u32(msg, &rid)) != 0) |
(r = sshbuf_get_u32(msg, &rid)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse"); |
__func__, ssh_err(r)); |
|
|
|
if (type != SSH2_FXP_STATUS) |
if (type != SSH2_FXP_STATUS) |
fatal("Expected SSH2_FXP_STATUS(%d) packet, " |
fatal("Expected SSH2_FXP_STATUS(%d) packet, " |
"got %d", SSH2_FXP_STATUS, type); |
"got %d", SSH2_FXP_STATUS, type); |
|
|
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
if ((r = sshbuf_get_u32(msg, &status)) != 0) |
fatal("%s: buffer error: %s", |
fatal_fr(r, "parse status"); |
__func__, ssh_err(r)); |
|
debug3("SSH2_FXP_STATUS %u", status); |
debug3("SSH2_FXP_STATUS %u", status); |
|
|
/* Find the request in our queue */ |
/* Find the request in our queue */ |
|
|
} |
} |
offset += len; |
offset += len; |
if (offset < 0) |
if (offset < 0) |
fatal("%s: offset < 0", __func__); |
fatal_f("offset < 0"); |
} |
} |
sshbuf_free(msg); |
sshbuf_free(msg); |
|
|