summaryrefslogtreecommitdiff
path: root/usr.bin/ssh
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2020-01-25 23:02:15 +0000
committerDamien Miller <djm@cvs.openbsd.org>2020-01-25 23:02:15 +0000
commit4f12d91895c4b4eb8ffcd3405fe00633f6138778 (patch)
tree0d53b594c37df9f3b29b64c5c47718642ff8bede /usr.bin/ssh
parent705d0e306d60f4da7a1686b3737936f929f00aa3 (diff)
factor out reading/writing sshbufs to dedicated functions;
feedback and ok markus@
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r--usr.bin/ssh/Makefile.inc4
-rw-r--r--usr.bin/ssh/authfile.c77
-rw-r--r--usr.bin/ssh/authfile.h3
-rw-r--r--usr.bin/ssh/krl.c16
-rw-r--r--usr.bin/ssh/ssh-add.c6
-rw-r--r--usr.bin/ssh/ssh-add/Makefile4
-rw-r--r--usr.bin/ssh/ssh-agent/Makefile4
-rw-r--r--usr.bin/ssh/ssh-keygen.c48
-rw-r--r--usr.bin/ssh/ssh-keygen/Makefile4
-rw-r--r--usr.bin/ssh/ssh-keysign/Makefile4
-rw-r--r--usr.bin/ssh/ssh/Makefile5
-rw-r--r--usr.bin/ssh/sshbuf-io.c116
-rw-r--r--usr.bin/ssh/sshbuf-misc.c15
-rw-r--r--usr.bin/ssh/sshbuf.h18
-rw-r--r--usr.bin/ssh/sshd/Makefile5
15 files changed, 183 insertions, 146 deletions
diff --git a/usr.bin/ssh/Makefile.inc b/usr.bin/ssh/Makefile.inc
index 5d7ac0bad40..6b2b9924a16 100644
--- a/usr.bin/ssh/Makefile.inc
+++ b/usr.bin/ssh/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.81 2020/01/23 10:24:29 dtucker Exp $
+# $OpenBSD: Makefile.inc,v 1.82 2020/01/25 23:02:13 djm Exp $
.include <bsd.own.mk>
@@ -99,6 +99,8 @@ SRCS_KEY+= verify.c
SRCS_KEY+= hash.c
SRCS_KEYP+= authfile.c
+SRCS_KEYP+= sshbuf-io.c
+SRCS_KEYP+= atomicio.c
SRCS_KRL+= bitmap.c
SRCS_KRL+= krl.c
diff --git a/usr.bin/ssh/authfile.c b/usr.bin/ssh/authfile.c
index 9c2a6838ef9..aeb903875ba 100644
--- a/usr.bin/ssh/authfile.c
+++ b/usr.bin/ssh/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.
*
@@ -53,20 +53,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
@@ -90,49 +83,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)
@@ -194,11 +144,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;
@@ -229,12 +175,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/usr.bin/ssh/authfile.h b/usr.bin/ssh/authfile.h
index a2840cf8082..1db067a813a 100644
--- a/usr.bin/ssh/authfile.h
+++ b/usr.bin/ssh/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/usr.bin/ssh/krl.c b/usr.bin/ssh/krl.c
index 1d00bfe38fe..dc9830e2d1a 100644
--- a/usr.bin/ssh/krl.c
+++ b/usr.bin/ssh/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 <sys/types.h>
#include <sys/tree.h>
@@ -1334,19 +1334,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;
}
@@ -1355,8 +1347,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/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c
index 80d3a1e067a..641b6cf2faf 100644
--- a/usr.bin/ssh/ssh-add.c
+++ b/usr.bin/ssh/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@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -217,9 +217,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/usr.bin/ssh/ssh-add/Makefile b/usr.bin/ssh/ssh-add/Makefile
index 4b10a2e8be0..93f92547f5f 100644
--- a/usr.bin/ssh/ssh-add/Makefile
+++ b/usr.bin/ssh/ssh-add/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.29 2019/12/13 19:09:10 djm Exp $
+# $OpenBSD: Makefile,v 1.30 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= ssh-add.c
-SRCS+= atomicio.c authfd.c cleanup.c fatal.c readpass.c
+SRCS+= authfd.c cleanup.c fatal.c readpass.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL}
SRCS+= ${SRCS_SK_CLIENT}
diff --git a/usr.bin/ssh/ssh-agent/Makefile b/usr.bin/ssh/ssh-agent/Makefile
index 0103b7a01fd..a263c18a74f 100644
--- a/usr.bin/ssh/ssh-agent/Makefile
+++ b/usr.bin/ssh/ssh-agent/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.36 2019/12/13 19:09:10 djm Exp $
+# $OpenBSD: Makefile,v 1.37 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= ssh-agent.c ${SRCS_PKCS11_CLIENT}
-SRCS+= atomicio.c compat.c fatal.c readpass.c
+SRCS+= compat.c fatal.c readpass.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL}
SRCS+= ${SRCS_SK_CLIENT}
diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c
index edbbe51c988..dba8f46b742 100644
--- a/usr.bin/ssh/ssh-keygen.c
+++ b/usr.bin/ssh/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@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2167,15 +2167,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)
@@ -2377,7 +2372,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;
@@ -2419,12 +2414,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);
@@ -2669,25 +2660,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;
@@ -2743,8 +2727,6 @@ done:
printf("Could not verify signature.\n");
}
}
- if (sigfd != -1)
- close(sigfd);
sshbuf_free(sigbuf);
sshbuf_free(abuf);
sshkey_free(sign_key);
@@ -2755,20 +2737,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;
}
@@ -2797,8 +2771,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/usr.bin/ssh/ssh-keygen/Makefile b/usr.bin/ssh/ssh-keygen/Makefile
index b128460fc85..8c9c92412ac 100644
--- a/usr.bin/ssh/ssh-keygen/Makefile
+++ b/usr.bin/ssh/ssh-keygen/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.37 2019/12/13 19:11:14 djm Exp $
+# $OpenBSD: Makefile,v 1.38 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= ssh-keygen.c ${SRCS_MODULI}
-SRCS+= atomicio.c authfd.c cleanup.c dns.c fatal.c hmac.c hostfile.c \
+SRCS+= authfd.c cleanup.c dns.c fatal.c hmac.c hostfile.c \
readpass.c utf8.c sshsig.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL} \
${SRCS_PKCS11} ${SRCS_SK_CLIENT}
diff --git a/usr.bin/ssh/ssh-keysign/Makefile b/usr.bin/ssh/ssh-keysign/Makefile
index 3f690c08aaa..7505ccda145 100644
--- a/usr.bin/ssh/ssh-keysign/Makefile
+++ b/usr.bin/ssh/ssh-keysign/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.19 2020/01/23 10:24:30 dtucker Exp $
+# $OpenBSD: Makefile,v 1.20 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= ssh-keysign.c readconf.c compat.c
-SRCS+= atomicio.c cleanup.c fatal.c
+SRCS+= cleanup.c fatal.c
SRCS+= uidswap.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_PKT} \
${SRCS_UTL} ${SRCS_SK_CLIENT}
diff --git a/usr.bin/ssh/ssh/Makefile b/usr.bin/ssh/ssh/Makefile
index 88cd05492e5..8ccf76c6b17 100644
--- a/usr.bin/ssh/ssh/Makefile
+++ b/usr.bin/ssh/ssh/Makefile
@@ -1,10 +1,9 @@
-# $OpenBSD: Makefile,v 1.80 2020/01/23 10:24:30 dtucker Exp $
+# $OpenBSD: Makefile,v 1.81 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
SRCS= ssh.c readconf.c clientloop.c sshtty.c sshconnect.c sshconnect2.c mux.c
-SRCS+= atomicio.c authfd.c compat.c dns.c fatal.c \
- hostfile.c readpass.c utf8.c
+SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c
SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXC} ${SRCS_KEY} ${SRCS_KEYP} \
${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \
${SRCS_SK_CLIENT}
diff --git a/usr.bin/ssh/sshbuf-io.c b/usr.bin/ssh/sshbuf-io.c
new file mode 100644
index 00000000000..108a8021948
--- /dev/null
+++ b/usr.bin/ssh/sshbuf-io.c
@@ -0,0 +1,116 @@
+/* $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 <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/usr.bin/ssh/sshbuf-misc.c b/usr.bin/ssh/sshbuf-misc.c
index b30eaeaabb3..20234b97321 100644
--- a/usr.bin/ssh/sshbuf-misc.c
+++ b/usr.bin/ssh/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
*
@@ -17,19 +17,24 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
+
+#include <ctype.h>
#include <errno.h>
-#include <stdlib.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <resolv.h>
#include <stdint.h>
#include <stdio.h>
-#include <limits.h>
+#include <stdlib.h>
#include <string.h>
-#include <resolv.h>
-#include <ctype.h>
+#include <unistd.h>
#include "ssherr.h"
#define SSHBUF_INTERNAL
#include "sshbuf.h"
+#include "atomicio.h"
void
sshbuf_dump_data(const void *s, size_t len, FILE *f)
diff --git a/usr.bin/ssh/sshbuf.h b/usr.bin/ssh/sshbuf.h
index 1288b92cc6e..dd194830ef4 100644
--- a/usr.bin/ssh/sshbuf.h
+++ b/usr.bin/ssh/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
*
@@ -292,6 +292,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) | \
diff --git a/usr.bin/ssh/sshd/Makefile b/usr.bin/ssh/sshd/Makefile
index bf6b73f60b6..51a2fefd9d1 100644
--- a/usr.bin/ssh/sshd/Makefile
+++ b/usr.bin/ssh/sshd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.103 2020/01/23 10:24:30 dtucker Exp $
+# $OpenBSD: Makefile,v 1.104 2020/01/25 23:02:14 djm Exp $
.PATH: ${.CURDIR}/..
@@ -7,8 +7,7 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c sshpty.c sshlogin.c servconf.c \
groupaccess.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \
auth2-none.c auth2-passwd.c auth2-pubkey.c monitor.c monitor_wrap.c \
sftp-server.c sftp-common.c sftp-realpath.c sandbox-pledge.c
-SRCS+= atomicio.c authfd.c compat.c dns.c fatal.c \
- hostfile.c readpass.c utf8.c uidswap.c
+SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c
SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \
${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \
${SRCS_SK_CLIENT}