1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-09 15:41:10 +03:00

sftpserver: Fix reading and writing if buffering occurs

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This commit is contained in:
Jakub Jelen
2023-03-01 11:00:03 +01:00
parent 94cbd58128
commit d0bfab2549

View File

@@ -883,7 +883,7 @@ process_read(sftp_client_message client_msg)
sftp_session sftp = client_msg->sftp; sftp_session sftp = client_msg->sftp;
ssh_string handle = client_msg->handle; ssh_string handle = client_msg->handle;
struct sftp_handle *h = NULL; struct sftp_handle *h = NULL;
uint32_t readn; ssize_t allreadn = 0;
int fd = -1; int fd = -1;
char *buffer = NULL; char *buffer = NULL;
int rv; int rv;
@@ -909,18 +909,18 @@ process_read(sftp_client_message client_msg)
} }
buffer = malloc(client_msg->len); buffer = malloc(client_msg->len);
readn = read(fd, buffer, client_msg->len); do {
ssize_t readn = read(fd, buffer + allreadn, client_msg->len - allreadn);
if (readn > 0) { if (readn < 0) {
sftp_reply_data(client_msg, buffer, readn);
} else if (readn == 0) {
sftp_reply_status(client_msg, SSH_FX_EOF, "EOF encountered");
} else {
sftp_reply_status(client_msg, SSH_FX_FAILURE, NULL); sftp_reply_status(client_msg, SSH_FX_FAILURE, NULL);
SSH_LOG(SSH_LOG_PROTOCOL, "read file error!"); SSH_LOG(SSH_LOG_PROTOCOL, "read file error!");
free(buffer); free(buffer);
return SSH_ERROR; return SSH_ERROR;
} }
allreadn += readn;
} while (allreadn < (ssize_t)client_msg->len);
sftp_reply_data(client_msg, buffer, allreadn);
free(buffer); free(buffer);
return SSH_OK; return SSH_OK;
@@ -932,7 +932,7 @@ process_write(sftp_client_message client_msg)
sftp_session sftp = client_msg->sftp; sftp_session sftp = client_msg->sftp;
ssh_string handle = client_msg->handle; ssh_string handle = client_msg->handle;
struct sftp_handle *h = NULL; struct sftp_handle *h = NULL;
int written; ssize_t written = 0;
int fd = -1; int fd = -1;
const char *msg_data = NULL; const char *msg_data = NULL;
uint32_t len; uint32_t len;
@@ -957,14 +957,17 @@ process_write(sftp_client_message client_msg)
SSH_LOG(SSH_LOG_PROTOCOL, "error seeking file at offset: %" PRIu64, SSH_LOG(SSH_LOG_PROTOCOL, "error seeking file at offset: %" PRIu64,
client_msg->offset); client_msg->offset);
} }
written = write(fd, msg_data, len); do {
if (written == (int)len) { rv = write(fd, msg_data + written, len - written);
sftp_reply_status(client_msg, SSH_FX_OK, NULL); if (rv < 0) {
} else if (written == -1) {
sftp_reply_status(client_msg, SSH_FX_FAILURE, "Write error"); sftp_reply_status(client_msg, SSH_FX_FAILURE, "Write error");
} else { SSH_LOG(SSH_LOG_PROTOCOL, "file write error!");
sftp_reply_status(client_msg, SSH_FX_FAILURE, "Partial write"); return SSH_ERROR;
} }
written += rv;
} while (written < (int)len);
sftp_reply_status(client_msg, SSH_FX_OK, NULL);
return SSH_OK; return SSH_OK;
} }