summaryrefslogtreecommitdiff
path: root/sshbuf-misc.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2022-01-22 00:43:43 +0000
committerDamien Miller <djm@mindrot.org>2022-01-25 10:45:47 +1100
commit754e0d5c7712296a7a3a83ace863812604c7bc4f (patch)
treed0b0afc8303791db5f40a8d6d4b639ba45d68a83 /sshbuf-misc.c
parentc7964fb9829d9ae2ece8b51a76e4a02e8449338d (diff)
downloadopenssh-git-754e0d5c7712296a7a3a83ace863812604c7bc4f.tar.gz
upstream: Add a sshbuf_read() that attempts to read(2) directly in
to a sshbuf; ok markus@ OpenBSD-Commit-ID: 2d8f249040a4279f3bc23c018947384de8d4a45b
Diffstat (limited to 'sshbuf-misc.c')
-rw-r--r--sshbuf-misc.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index 80714d1f..9c5c42bb 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshbuf-misc.c,v 1.17 2021/08/11 05:21:32 djm Exp $ */
+/* $OpenBSD: sshbuf-misc.c,v 1.18 2022/01/22 00:43:43 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -30,6 +30,7 @@
#include <string.h>
#include <resolv.h>
#include <ctype.h>
+#include <unistd.h>
#include "ssherr.h"
#define SSHBUF_INTERNAL
@@ -269,3 +270,39 @@ sshbuf_find(const struct sshbuf *b, size_t start_offset,
*offsetp = (const u_char *)p - sshbuf_ptr(b);
return 0;
}
+
+int
+sshbuf_read(int fd, struct sshbuf *buf, size_t maxlen, size_t *rlen)
+{
+ int r, oerrno;
+ size_t adjust;
+ ssize_t rr;
+ u_char *d;
+
+ if (rlen != NULL)
+ *rlen = 0;
+ if ((r = sshbuf_reserve(buf, maxlen, &d)) != 0)
+ return r;
+ rr = read(fd, d, maxlen);
+ oerrno = errno;
+
+ /* Adjust the buffer to include only what was actually read */
+ if ((adjust = maxlen - (rr > 0 ? rr : 0)) != 0) {
+ if ((r = sshbuf_consume_end(buf, adjust)) != 0) {
+ /* avoid returning uninitialised data to caller */
+ memset(d + rr, '\0', adjust);
+ return SSH_ERR_INTERNAL_ERROR; /* shouldn't happen */
+ }
+ }
+ if (rr < 0) {
+ errno = oerrno;
+ return SSH_ERR_SYSTEM_ERROR;
+ } else if (rr == 0) {
+ errno = EPIPE;
+ return SSH_ERR_SYSTEM_ERROR;
+ }
+ /* success */
+ if (rlen != NULL)
+ *rlen = (size_t)rr;
+ return 0;
+}