upstream: factor out reading/writing sshbufs to dedicated
functions; feedback and ok markus@ OpenBSD-Commit-ID: dc09e5f1950b7acc91b8fdf8015347782d2ecd3d
This commit is contained in:
parent
065064fcf4
commit
99aa803555
|
@ -109,7 +109,8 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
|
||||||
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
|
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
|
||||||
kexgexc.o kexgexs.o \
|
kexgexc.o kexgexs.o \
|
||||||
sntrup4591761.o kexsntrup4591761x25519.o kexgen.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
|
SKOBJS= ssh-sk-client.o
|
||||||
|
|
||||||
|
|
77
authfile.c
77
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.
|
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -55,20 +55,13 @@
|
||||||
static int
|
static int
|
||||||
sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
|
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)
|
omask = umask(077);
|
||||||
return SSH_ERR_SYSTEM_ERROR;
|
r = sshbuf_write_file(filename, keybuf);
|
||||||
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keybuf),
|
umask(omask);
|
||||||
sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
|
return r;
|
||||||
oerrno = errno;
|
|
||||||
close(fd);
|
|
||||||
unlink(filename);
|
|
||||||
errno = oerrno;
|
|
||||||
return SSH_ERR_SYSTEM_ERROR;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -92,49 +85,6 @@ sshkey_save_private(struct sshkey *key, const char *filename,
|
||||||
return r;
|
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? */
|
/* XXX remove error() calls from here? */
|
||||||
int
|
int
|
||||||
sshkey_perm_ok(int fd, const char *filename)
|
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)
|
if (keyp != NULL)
|
||||||
*keyp = NULL;
|
*keyp = NULL;
|
||||||
if ((buffer = sshbuf_new()) == NULL) {
|
if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
|
||||||
r = SSH_ERR_ALLOC_FAIL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((r = sshkey_load_file(fd, buffer)) != 0 ||
|
|
||||||
(r = sshkey_parse_private_fileblob_type(buffer, type,
|
(r = sshkey_parse_private_fileblob_type(buffer, type,
|
||||||
passphrase, keyp, commentp)) != 0)
|
passphrase, keyp, commentp)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -234,12 +180,7 @@ sshkey_load_private(const char *filename, const char *passphrase,
|
||||||
r = SSH_ERR_KEY_BAD_PERMISSIONS;
|
r = SSH_ERR_KEY_BAD_PERMISSIONS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
|
||||||
if ((buffer = sshbuf_new()) == NULL) {
|
|
||||||
r = SSH_ERR_ALLOC_FAIL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((r = sshkey_load_file(fd, buffer)) != 0 ||
|
|
||||||
(r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
|
(r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,
|
||||||
commentp)) != 0)
|
commentp)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -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.
|
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
|
||||||
|
@ -35,7 +35,6 @@ struct sshkey;
|
||||||
|
|
||||||
int sshkey_save_private(struct sshkey *, const char *,
|
int sshkey_save_private(struct sshkey *, const char *,
|
||||||
const char *, const char *, int, const char *, int);
|
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_cert(const char *, struct sshkey **);
|
||||||
int sshkey_load_public(const char *, struct sshkey **, char **);
|
int sshkey_load_public(const char *, struct sshkey **, char **);
|
||||||
int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
|
int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
|
||||||
|
|
16
krl.c
16
krl.c
|
@ -14,7 +14,7 @@
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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"
|
#include "includes.h"
|
||||||
|
|
||||||
|
@ -1336,19 +1336,11 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
|
||||||
{
|
{
|
||||||
struct sshbuf *krlbuf = NULL;
|
struct sshbuf *krlbuf = NULL;
|
||||||
struct ssh_krl *krl = NULL;
|
struct ssh_krl *krl = NULL;
|
||||||
int oerrno = 0, r, fd;
|
int oerrno = 0, r;
|
||||||
|
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
if ((r = sshbuf_load_file(path, &krlbuf)) != 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) {
|
|
||||||
oerrno = errno;
|
oerrno = errno;
|
||||||
goto out;
|
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);
|
debug2("%s: checking KRL %s", __func__, path);
|
||||||
r = ssh_krl_check_key(krl, key);
|
r = ssh_krl_check_key(krl, key);
|
||||||
out:
|
out:
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
sshbuf_free(krlbuf);
|
sshbuf_free(krlbuf);
|
||||||
ssh_krl_free(krl);
|
ssh_krl_free(krl);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
|
|
|
@ -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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -224,9 +224,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((keyblob = sshbuf_new()) == NULL)
|
if ((r = sshbuf_load_fd(fd, &keyblob)) != 0) {
|
||||||
fatal("%s: sshbuf_new failed", __func__);
|
|
||||||
if ((r = sshkey_load_file(fd, keyblob)) != 0) {
|
|
||||||
fprintf(stderr, "Error loading key \"%s\": %s\n",
|
fprintf(stderr, "Error loading key \"%s\": %s\n",
|
||||||
filename, ssh_err(r));
|
filename, ssh_err(r));
|
||||||
sshbuf_free(keyblob);
|
sshbuf_free(keyblob);
|
||||||
|
|
48
ssh-keygen.c
48
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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -2189,15 +2189,10 @@ static void
|
||||||
load_krl(const char *path, struct ssh_krl **krlp)
|
load_krl(const char *path, struct ssh_krl **krlp)
|
||||||
{
|
{
|
||||||
struct sshbuf *krlbuf;
|
struct sshbuf *krlbuf;
|
||||||
int r, fd;
|
int r;
|
||||||
|
|
||||||
if ((krlbuf = sshbuf_new()) == NULL)
|
if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
|
||||||
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)
|
|
||||||
fatal("Unable to load KRL: %s", ssh_err(r));
|
fatal("Unable to load KRL: %s", ssh_err(r));
|
||||||
close(fd);
|
|
||||||
/* XXX check sigs */
|
/* XXX check sigs */
|
||||||
if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
|
if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
|
||||||
*krlp == NULL)
|
*krlp == NULL)
|
||||||
|
@ -2399,7 +2394,7 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
|
||||||
struct ssh_krl *krl;
|
struct ssh_krl *krl;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
struct sshkey *ca = NULL;
|
struct sshkey *ca = NULL;
|
||||||
int fd, i, r, wild_ca = 0;
|
int i, r, wild_ca = 0;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
struct sshbuf *kbuf;
|
struct sshbuf *kbuf;
|
||||||
|
|
||||||
|
@ -2441,12 +2436,8 @@ do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
|
||||||
fatal("sshbuf_new failed");
|
fatal("sshbuf_new failed");
|
||||||
if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
|
if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
|
||||||
fatal("Couldn't generate KRL");
|
fatal("Couldn't generate KRL");
|
||||||
if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
|
if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
|
||||||
fatal("open %s: %s", identity_file, strerror(errno));
|
|
||||||
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(kbuf), sshbuf_len(kbuf)) !=
|
|
||||||
sshbuf_len(kbuf))
|
|
||||||
fatal("write %s: %s", identity_file, strerror(errno));
|
fatal("write %s: %s", identity_file, strerror(errno));
|
||||||
close(fd);
|
|
||||||
sshbuf_free(kbuf);
|
sshbuf_free(kbuf);
|
||||||
ssh_krl_free(krl);
|
ssh_krl_free(krl);
|
||||||
sshkey_free(ca);
|
sshkey_free(ca);
|
||||||
|
@ -2691,25 +2682,18 @@ static int
|
||||||
sig_verify(const char *signature, const char *sig_namespace,
|
sig_verify(const char *signature, const char *sig_namespace,
|
||||||
const char *principal, const char *allowed_keys, const char *revoked_keys)
|
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 sshbuf *sigbuf = NULL, *abuf = NULL;
|
||||||
struct sshkey *sign_key = NULL;
|
struct sshkey *sign_key = NULL;
|
||||||
char *fp = NULL;
|
char *fp = NULL;
|
||||||
struct sshkey_sig_details *sig_details = NULL;
|
struct sshkey_sig_details *sig_details = NULL;
|
||||||
|
|
||||||
memset(&sig_details, 0, sizeof(sig_details));
|
memset(&sig_details, 0, sizeof(sig_details));
|
||||||
if ((abuf = sshbuf_new()) == NULL)
|
if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
|
||||||
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) {
|
|
||||||
error("Couldn't read signature file: %s", ssh_err(r));
|
error("Couldn't read signature file: %s", ssh_err(r));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
|
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
|
||||||
error("%s: sshsig_armor: %s", __func__, ssh_err(r));
|
error("%s: sshsig_armor: %s", __func__, ssh_err(r));
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -2765,8 +2749,6 @@ done:
|
||||||
printf("Could not verify signature.\n");
|
printf("Could not verify signature.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sigfd != -1)
|
|
||||||
close(sigfd);
|
|
||||||
sshbuf_free(sigbuf);
|
sshbuf_free(sigbuf);
|
||||||
sshbuf_free(abuf);
|
sshbuf_free(abuf);
|
||||||
sshkey_free(sign_key);
|
sshkey_free(sign_key);
|
||||||
|
@ -2777,20 +2759,12 @@ done:
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sig_find_principals(const char *signature, const char *allowed_keys) {
|
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 sshbuf *sigbuf = NULL, *abuf = NULL;
|
||||||
struct sshkey *sign_key = NULL;
|
struct sshkey *sign_key = NULL;
|
||||||
char *principals = NULL, *cp, *tmp;
|
char *principals = NULL, *cp, *tmp;
|
||||||
|
|
||||||
if ((abuf = sshbuf_new()) == NULL)
|
if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
|
||||||
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) {
|
|
||||||
error("Couldn't read signature file: %s", ssh_err(r));
|
error("Couldn't read signature file: %s", ssh_err(r));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -2819,8 +2793,6 @@ done:
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "No principal matched.\n");
|
fprintf(stderr, "No principal matched.\n");
|
||||||
}
|
}
|
||||||
if (sigfd != -1)
|
|
||||||
close(sigfd);
|
|
||||||
sshbuf_free(sigbuf);
|
sshbuf_free(sigbuf);
|
||||||
sshbuf_free(abuf);
|
sshbuf_free(abuf);
|
||||||
sshkey_free(sign_key);
|
sshkey_free(sign_key);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
* Copyright (c) 2011 Damien Miller
|
||||||
*
|
*
|
||||||
|
|
18
sshbuf.h
18
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
|
* 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);
|
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 */
|
/* Macros for decoding/encoding integers */
|
||||||
#define PEEK_U64(p) \
|
#define PEEK_U64(p) \
|
||||||
(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
|
(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
|
||||||
|
|
Loading…
Reference in New Issue