[openssh-commits] [openssh] 04/08: upstream: factor out reading/writing sshbufs to dedicated

git+noreply at mindrot.org git+noreply at mindrot.org
Sun Jan 26 10:35:00 AEDT 2020


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 99aa8035554ddb976348d2a9253ab3653019728d
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Sat Jan 25 23:02:13 2020 +0000

    upstream: factor out reading/writing sshbufs to dedicated
    
    functions; feedback and ok markus@
    
    OpenBSD-Commit-ID: dc09e5f1950b7acc91b8fdf8015347782d2ecd3d
---
 Makefile.in   |   3 +-
 authfile.c    |  77 +++++---------------------------------
 authfile.h    |   3 +-
 krl.c         |  16 ++------
 ssh-add.c     |   6 +--
 ssh-keygen.c  |  48 +++++-------------------
 sshbuf-io.c   | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sshbuf-misc.c |   2 +-
 sshbuf.h      |  18 ++++++++-
 9 files changed, 163 insertions(+), 128 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 963f99fb..e7549470 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -109,7 +109,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
 	kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
 	kexgexc.o kexgexs.o \
 	sntrup4591761.o kexsntrup4591761x25519.o kexgen.o \
-	sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o
+	sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
+	sshbuf-io.o
 
 SKOBJS=	ssh-sk-client.o
 
diff --git a/authfile.c b/authfile.c
index bf22d63e..20b66d9b 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.c,v 1.136 2020/01/02 22:38:33 djm Exp $ */
+/* $OpenBSD: authfile.c,v 1.137 2020/01/25 23:02:13 djm Exp $ */
 /*
  * Copyright (c) 2000, 2013 Markus Friedl.  All rights reserved.
  *
@@ -55,20 +55,13 @@
 static int
 sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
 {
-	int fd, oerrno;
+	int r;
+	mode_t omask;
 
-	if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1)
-		return SSH_ERR_SYSTEM_ERROR;
-	if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keybuf),
-	    sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
-		oerrno = errno;
-		close(fd);
-		unlink(filename);
-		errno = oerrno;
-		return SSH_ERR_SYSTEM_ERROR;
-	}
-	close(fd);
-	return 0;
+	omask = umask(077);
+	r = sshbuf_write_file(filename, keybuf);
+	umask(omask);
+	return r;
 }
 
 int
@@ -92,49 +85,6 @@ sshkey_save_private(struct sshkey *key, const char *filename,
 	return r;
 }
 
-/* Load a key from a fd into a buffer */
-int
-sshkey_load_file(int fd, struct sshbuf *blob)
-{
-	u_char buf[1024];
-	size_t len;
-	struct stat st;
-	int r;
-
-	if (fstat(fd, &st) == -1)
-		return SSH_ERR_SYSTEM_ERROR;
-	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
-	    st.st_size > MAX_KEY_FILE_SIZE)
-		return SSH_ERR_INVALID_FORMAT;
-	for (;;) {
-		if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
-			if (errno == EPIPE)
-				break;
-			r = SSH_ERR_SYSTEM_ERROR;
-			goto out;
-		}
-		if ((r = sshbuf_put(blob, buf, len)) != 0)
-			goto out;
-		if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {
-			r = SSH_ERR_INVALID_FORMAT;
-			goto out;
-		}
-	}
-	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
-	    st.st_size != (off_t)sshbuf_len(blob)) {
-		r = SSH_ERR_FILE_CHANGED;
-		goto out;
-	}
-	r = 0;
-
- out:
-	explicit_bzero(buf, sizeof(buf));
-	if (r != 0)
-		sshbuf_reset(blob);
-	return r;
-}
-
-
 /* XXX remove error() calls from here? */
 int
 sshkey_perm_ok(int fd, const char *filename)
@@ -199,11 +149,7 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
 
 	if (keyp != NULL)
 		*keyp = NULL;
-	if ((buffer = sshbuf_new()) == NULL) {
-		r = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
-	if ((r = sshkey_load_file(fd, buffer)) != 0 ||
+	if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
 	    (r = sshkey_parse_private_fileblob_type(buffer, type,
 	    passphrase, keyp, commentp)) != 0)
 		goto out;
@@ -234,12 +180,7 @@ sshkey_load_private(const char *filename, const char *passphrase,
 		r = SSH_ERR_KEY_BAD_PERMISSIONS;
 		goto out;
 	}
-
-	if ((buffer = sshbuf_new()) == NULL) {
-		r = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
-	if ((r = sshkey_load_file(fd, buffer)) != 0 ||
+	if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
 	    (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
 	    commentp)) != 0)
 		goto out;
diff --git a/authfile.h b/authfile.h
index a2840cf8..1db067a8 100644
--- a/authfile.h
+++ b/authfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.h,v 1.24 2020/01/02 22:38:33 djm Exp $ */
+/* $OpenBSD: authfile.h,v 1.25 2020/01/25 23:02:13 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2013 Markus Friedl.  All rights reserved.
@@ -35,7 +35,6 @@ struct sshkey;
 
 int sshkey_save_private(struct sshkey *, const char *,
     const char *, const char *, int, const char *, int);
-int sshkey_load_file(int, struct sshbuf *);
 int sshkey_load_cert(const char *, struct sshkey **);
 int sshkey_load_public(const char *, struct sshkey **, char **);
 int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
diff --git a/krl.c b/krl.c
index aa8318cf..03476ded 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $OpenBSD: krl.c,v 1.46 2019/11/25 00:51:37 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.47 2020/01/25 23:02:13 djm Exp $ */
 
 #include "includes.h"
 
@@ -1336,19 +1336,11 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
 {
 	struct sshbuf *krlbuf = NULL;
 	struct ssh_krl *krl = NULL;
-	int oerrno = 0, r, fd;
+	int oerrno = 0, r;
 
 	if (path == NULL)
 		return 0;
-
-	if ((krlbuf = sshbuf_new()) == NULL)
-		return SSH_ERR_ALLOC_FAIL;
-	if ((fd = open(path, O_RDONLY)) == -1) {
-		r = SSH_ERR_SYSTEM_ERROR;
-		oerrno = errno;
-		goto out;
-	}
-	if ((r = sshkey_load_file(fd, krlbuf)) != 0) {
+	if ((r = sshbuf_load_file(path, &krlbuf)) != 0) {
 		oerrno = errno;
 		goto out;
 	}
@@ -1357,8 +1349,6 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
 	debug2("%s: checking KRL %s", __func__, path);
 	r = ssh_krl_check_key(krl, key);
  out:
-	if (fd != -1)
-		close(fd);
 	sshbuf_free(krlbuf);
 	ssh_krl_free(krl);
 	if (r != 0)
diff --git a/ssh-add.c b/ssh-add.c
index 980caa46..f3b666c9 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.150 2020/01/17 20:13:47 naddy Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.151 2020/01/25 23:02:13 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -224,9 +224,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
 			return -1;
 		}
 	}
-	if ((keyblob = sshbuf_new()) == NULL)
-		fatal("%s: sshbuf_new failed", __func__);
-	if ((r = sshkey_load_file(fd, keyblob)) != 0) {
+	if ((r = sshbuf_load_fd(fd, &keyblob)) != 0) {
 		fprintf(stderr, "Error loading key \"%s\": %s\n",
 		    filename, ssh_err(r));
 		sshbuf_free(keyblob);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index d29f97bb..29013a20 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.392 2020/01/25 00:03:36 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.393 2020/01/25 23:02:13 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -2189,15 +2189,10 @@ static void
 load_krl(const char *path, struct ssh_krl **krlp)
 {
 	struct sshbuf *krlbuf;
-	int r, fd;
+	int r;
 
-	if ((krlbuf = sshbuf_new()) == NULL)
-		fatal("sshbuf_new failed");
-	if ((fd = open(path, O_RDONLY)) == -1)
-		fatal("open %s: %s", path, strerror(errno));
-	if ((r = sshkey_load_file(fd, krlbuf)) != 0)
+	if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
 		fatal("Unable to load KRL: %s", ssh_err(r));
-	close(fd);
 	/* XXX check sigs */
 	if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
 	    *krlp == NULL)
@@ -2399,7 +2394,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
 	struct ssh_krl *krl;
 	struct stat sb;
 	struct sshkey *ca = NULL;
-	int fd, i, r, wild_ca = 0;
+	int i, r, wild_ca = 0;
 	char *tmp;
 	struct sshbuf *kbuf;
 
@@ -2441,12 +2436,8 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
 		fatal("sshbuf_new failed");
 	if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
 		fatal("Couldn't generate KRL");
-	if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
-		fatal("open %s: %s", identity_file, strerror(errno));
-	if (atomicio(vwrite, fd, sshbuf_mutable_ptr(kbuf), sshbuf_len(kbuf)) !=
-	    sshbuf_len(kbuf))
+	if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
 		fatal("write %s: %s", identity_file, strerror(errno));
-	close(fd);
 	sshbuf_free(kbuf);
 	ssh_krl_free(krl);
 	sshkey_free(ca);
@@ -2691,25 +2682,18 @@ static int
 sig_verify(const char *signature, const char *sig_namespace,
     const char *principal, const char *allowed_keys, const char *revoked_keys)
 {
-	int r, ret = -1, sigfd = -1;
+	int r, ret = -1;
 	struct sshbuf *sigbuf = NULL, *abuf = NULL;
 	struct sshkey *sign_key = NULL;
 	char *fp = NULL;
 	struct sshkey_sig_details *sig_details = NULL;
 
 	memset(&sig_details, 0, sizeof(sig_details));
-	if ((abuf = sshbuf_new()) == NULL)
-		fatal("%s: sshbuf_new() failed", __func__);
-
-	if ((sigfd = open(signature, O_RDONLY)) < 0) {
-		error("Couldn't open signature file %s", signature);
-		goto done;
-	}
-
-	if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
+	if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
 		error("Couldn't read signature file: %s", ssh_err(r));
 		goto done;
 	}
+
 	if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
 		error("%s: sshsig_armor: %s", __func__, ssh_err(r));
 		goto done;
@@ -2765,8 +2749,6 @@ done:
 			printf("Could not verify signature.\n");
 		}
 	}
-	if (sigfd != -1)
-		close(sigfd);
 	sshbuf_free(sigbuf);
 	sshbuf_free(abuf);
 	sshkey_free(sign_key);
@@ -2777,20 +2759,12 @@ done:
 
 static int
 sig_find_principals(const char *signature, const char *allowed_keys) {
-	int r, ret = -1, sigfd = -1;
+	int r, ret = -1;
 	struct sshbuf *sigbuf = NULL, *abuf = NULL;
 	struct sshkey *sign_key = NULL;
 	char *principals = NULL, *cp, *tmp;
 
-	if ((abuf = sshbuf_new()) == NULL)
-		fatal("%s: sshbuf_new() failed", __func__);
-
-	if ((sigfd = open(signature, O_RDONLY)) < 0) {
-		error("Couldn't open signature file %s", signature);
-		goto done;
-	}
-
-	if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
+	if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
 		error("Couldn't read signature file: %s", ssh_err(r));
 		goto done;
 	}
@@ -2819,8 +2793,6 @@ done:
 	} else {
 		fprintf(stderr, "No principal matched.\n");
 	}
-	if (sigfd != -1)
-		close(sigfd);
 	sshbuf_free(sigbuf);
 	sshbuf_free(abuf);
 	sshkey_free(sign_key);
diff --git a/sshbuf-io.c b/sshbuf-io.c
new file mode 100644
index 00000000..65f74585
--- /dev/null
+++ b/sshbuf-io.c
@@ -0,0 +1,118 @@
+/*	$OpenBSD: sshbuf-io.c,v 1.1 2020/01/25 23:02:14 djm Exp $ */
+/*
+ * Copyright (c) 2011 Damien Miller
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "ssherr.h"
+#define SSHBUF_INTERNAL
+#include "sshbuf.h"
+#include "atomicio.h"
+
+/* Load a file from a fd into a buffer */
+int
+sshbuf_load_fd(int fd, struct sshbuf **blobp)
+{
+	u_char buf[4096];
+	size_t len;
+	struct stat st;
+	int r;
+	struct sshbuf *blob;
+
+	*blobp = NULL;
+
+	if (fstat(fd, &st) == -1)
+		return SSH_ERR_SYSTEM_ERROR;
+	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
+	    st.st_size > SSHBUF_SIZE_MAX)
+		return SSH_ERR_INVALID_FORMAT;
+	if ((blob = sshbuf_new()) == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+	for (;;) {
+		if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
+			if (errno == EPIPE)
+				break;
+			r = SSH_ERR_SYSTEM_ERROR;
+			goto out;
+		}
+		if ((r = sshbuf_put(blob, buf, len)) != 0)
+			goto out;
+		if (sshbuf_len(blob) > SSHBUF_SIZE_MAX) {
+			r = SSH_ERR_INVALID_FORMAT;
+			goto out;
+		}
+	}
+	if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
+	    st.st_size != (off_t)sshbuf_len(blob)) {
+		r = SSH_ERR_FILE_CHANGED;
+		goto out;
+	}
+	/* success */
+	*blobp = blob;
+	blob = NULL; /* transferred */
+	r = 0;
+ out:
+	explicit_bzero(buf, sizeof(buf));
+	sshbuf_free(blob);
+	return r;
+}
+
+int
+sshbuf_load_file(const char *path, struct sshbuf **bufp)
+{
+	int r, fd, oerrno;
+
+	*bufp = NULL;
+	if ((fd = open(path, O_RDONLY)) == -1)
+		return SSH_ERR_SYSTEM_ERROR;
+	if ((r = sshbuf_load_fd(fd, bufp)) != 0)
+		goto out;
+	/* success */
+	r = 0;
+ out:
+	oerrno = errno;
+	close(fd);
+	if (r != 0)
+		errno = oerrno;
+	return r;
+}
+
+int
+sshbuf_write_file(const char *path, struct sshbuf *buf)
+{
+	int fd, oerrno;
+
+	if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
+		return SSH_ERR_SYSTEM_ERROR;
+	if (atomicio(vwrite, fd, sshbuf_mutable_ptr(buf),
+	    sshbuf_len(buf)) != sshbuf_len(buf) || close(fd) != 0) {
+		oerrno = errno;
+		close(fd);
+		unlink(path);
+		errno = oerrno;
+		return SSH_ERR_SYSTEM_ERROR;
+	}
+	return 0;
+}
+
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index a73f008b..739b19f9 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: sshbuf-misc.c,v 1.11 2019/07/30 05:04:49 djm Exp $	*/
+/*	$OpenBSD: sshbuf-misc.c,v 1.12 2020/01/25 23:02:14 djm Exp $	*/
 /*
  * Copyright (c) 2011 Damien Miller
  *
diff --git a/sshbuf.h b/sshbuf.h
index ebd64b10..165cd0b1 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: sshbuf.h,v 1.18 2019/09/06 05:23:55 djm Exp $	*/
+/*	$OpenBSD: sshbuf.h,v 1.19 2020/01/25 23:02:14 djm Exp $	*/
 /*
  * Copyright (c) 2011 Damien Miller
  *
@@ -291,6 +291,22 @@ sshbuf_find(const struct sshbuf *b, size_t start_offset,
  */
 char *sshbuf_dup_string(struct sshbuf *buf);
 
+/*
+ * Fill a buffer from a file descriptor or filename. Both allocate the
+ * buffer for the caller.
+ */
+int sshbuf_load_fd(int, struct sshbuf **)
+    __attribute__((__nonnull__ (2)));
+int sshbuf_load_file(const char *, struct sshbuf **)
+    __attribute__((__nonnull__ (2)));
+
+/*
+ * Write a buffer to a path, creating/truncating as needed (mode 0644,
+ * subject to umask). The buffer contents are not modified.
+ */
+int sshbuf_write_file(const char *path, struct sshbuf *buf)
+    __attribute__((__nonnull__ (2)));
+
 /* Macros for decoding/encoding integers */
 #define PEEK_U64(p) \
 	(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list