From 53abe6d4e4d87ec60c81a13aba32de5341d99c3f Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sun, 21 Dec 2014 17:39:07 -0500 Subject: [PATCH] and that is the last of the stock openssh 6.7 commits --- openssh/misc.h | 138 ++++++++++ openssh/openbsd-compat/getopt.h | 74 ++++++ openssh/openbsd-compat/strmode.c | 148 +++++++++++ openssh/sshbuf-getput-basic.c | 421 +++++++++++++++++++++++++++++++ openssh/ssherr.h | 80 ++++++ openssh/xmalloc.h | 25 ++ 6 files changed, 886 insertions(+) create mode 100644 openssh/misc.h create mode 100644 openssh/openbsd-compat/getopt.h create mode 100644 openssh/openbsd-compat/strmode.c create mode 100644 openssh/sshbuf-getput-basic.c create mode 100644 openssh/ssherr.h create mode 100644 openssh/xmalloc.h diff --git a/openssh/misc.h b/openssh/misc.h new file mode 100644 index 0000000..374c33c --- /dev/null +++ b/openssh/misc.h @@ -0,0 +1,138 @@ +/* $OpenBSD: misc.h,v 1.54 2014/07/15 15:54:14 millert Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef _MISC_H +#define _MISC_H + +/* Data structure for representing a forwarding request. */ +struct Forward { + char *listen_host; /* Host (address) to listen on. */ + int listen_port; /* Port to forward. */ + char *listen_path; /* Path to bind domain socket. */ + char *connect_host; /* Host to connect. */ + int connect_port; /* Port to connect on connect_host. */ + char *connect_path; /* Path to connect domain socket. */ + int allocated_port; /* Dynamically allocated listen port */ + int handle; /* Handle for dynamic listen ports */ +}; + +/* Common server and client forwarding options. */ +struct ForwardOptions { + int gateway_ports; /* Allow remote connects to forwarded ports. */ + mode_t streamlocal_bind_mask; /* umask for streamlocal binds */ + int streamlocal_bind_unlink; /* unlink socket before bind */ +}; + +/* misc.c */ + +char *chop(char *); +char *strdelim(char **); +int set_nonblock(int); +int unset_nonblock(int); +void set_nodelay(int); +int a2port(const char *); +int a2tun(const char *, int *); +char *put_host_port(const char *, u_short); +char *hpdelim(char **); +char *cleanhostname(char *); +char *colon(char *); +long convtime(const char *); +char *tilde_expand_filename(const char *, uid_t); +char *percent_expand(const char *, ...) __attribute__((__sentinel__)); +char *tohex(const void *, size_t); +void sanitise_stdfd(void); +void ms_subtract_diff(struct timeval *, int *); +void ms_to_timeval(struct timeval *, int); +time_t monotime(void); +void lowercase(char *s); +int unix_listener(const char *, int, int); + +void sock_set_v6only(int); + +struct passwd *pwcopy(struct passwd *); +const char *ssh_gai_strerror(int); + +typedef struct arglist arglist; +struct arglist { + char **list; + u_int num; + u_int nalloc; +}; +void addargs(arglist *, char *, ...) + __attribute__((format(printf, 2, 3))); +void replacearg(arglist *, u_int, char *, ...) + __attribute__((format(printf, 3, 4))); +void freeargs(arglist *); + +int tun_open(int, int); + +/* Common definitions for ssh tunnel device forwarding */ +#define SSH_TUNMODE_NO 0x00 +#define SSH_TUNMODE_POINTOPOINT 0x01 +#define SSH_TUNMODE_ETHERNET 0x02 +#define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT +#define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET) + +#define SSH_TUNID_ANY 0x7fffffff +#define SSH_TUNID_ERR (SSH_TUNID_ANY - 1) +#define SSH_TUNID_MAX (SSH_TUNID_ANY - 2) + +/* Fake port to indicate that host field is really a path. */ +#define PORT_STREAMLOCAL -2 + +/* Functions to extract or store big-endian words of various sizes */ +u_int64_t get_u64(const void *) + __attribute__((__bounded__( __minbytes__, 1, 8))); +u_int32_t get_u32(const void *) + __attribute__((__bounded__( __minbytes__, 1, 4))); +u_int16_t get_u16(const void *) + __attribute__((__bounded__( __minbytes__, 1, 2))); +void put_u64(void *, u_int64_t) + __attribute__((__bounded__( __minbytes__, 1, 8))); +void put_u32(void *, u_int32_t) + __attribute__((__bounded__( __minbytes__, 1, 4))); +void put_u16(void *, u_int16_t) + __attribute__((__bounded__( __minbytes__, 1, 2))); + +/* Little-endian store/load, used by umac.c */ +u_int32_t get_u32_le(const void *) + __attribute__((__bounded__(__minbytes__, 1, 4))); +void put_u32_le(void *, u_int32_t) + __attribute__((__bounded__(__minbytes__, 1, 4))); + +struct bwlimit { + size_t buflen; + u_int64_t rate, thresh, lamt; + struct timeval bwstart, bwend; +}; + +void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); +void bandwidth_limit(struct bwlimit *, size_t); + +int parse_ipqos(const char *); +const char *iptos2str(int); +void mktemp_proto(char *, size_t); + +/* readpass.c */ + +#define RP_ECHO 0x0001 +#define RP_ALLOW_STDIN 0x0002 +#define RP_ALLOW_EOF 0x0004 +#define RP_USE_ASKPASS 0x0008 + +char *read_passphrase(const char *, int); +int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); +int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); + +#endif /* _MISC_H */ diff --git a/openssh/openbsd-compat/getopt.h b/openssh/openbsd-compat/getopt.h new file mode 100644 index 0000000..8eb1244 --- /dev/null +++ b/openssh/openbsd-compat/getopt.h @@ -0,0 +1,74 @@ +/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +/* + * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions + */ +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +int getopt_long_only(int, char * const *, const char *, + const struct option *, int *); +#ifndef _GETOPT_DEFINED_ +#define _GETOPT_DEFINED_ +int getopt(int, char * const *, const char *); +int getsubopt(char **, char * const *, char **); + +extern char *optarg; /* getopt(3) external variables */ +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +extern char *suboptarg; /* getsubopt(3) external variable */ +#endif + +#endif /* !_GETOPT_H_ */ diff --git a/openssh/openbsd-compat/strmode.c b/openssh/openbsd-compat/strmode.c new file mode 100644 index 0000000..4a81614 --- /dev/null +++ b/openssh/openbsd-compat/strmode.c @@ -0,0 +1,148 @@ +/* $OpenBSD: strmode.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strmode.c */ + +#include "includes.h" +#ifndef HAVE_STRMODE + +#include +#include +#include + +/* XXX mode should be mode_t */ + +void +strmode(int mode, char *p) +{ + /* print type */ + switch (mode & S_IFMT) { + case S_IFDIR: /* directory */ + *p++ = 'd'; + break; + case S_IFCHR: /* character special */ + *p++ = 'c'; + break; + case S_IFBLK: /* block special */ + *p++ = 'b'; + break; + case S_IFREG: /* regular */ + *p++ = '-'; + break; + case S_IFLNK: /* symbolic link */ + *p++ = 'l'; + break; +#ifdef S_IFSOCK + case S_IFSOCK: /* socket */ + *p++ = 's'; + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: /* fifo */ + *p++ = 'p'; + break; +#endif + default: /* unknown */ + *p++ = '?'; + break; + } + /* usr */ + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR | S_ISUID)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + case S_ISUID: + *p++ = 'S'; + break; + case S_IXUSR | S_ISUID: + *p++ = 's'; + break; + } + /* group */ + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP | S_ISGID)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + case S_ISGID: + *p++ = 'S'; + break; + case S_IXGRP | S_ISGID: + *p++ = 's'; + break; + } + /* other */ + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH | S_ISVTX)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + case S_ISVTX: + *p++ = 'T'; + break; + case S_IXOTH | S_ISVTX: + *p++ = 't'; + break; + } + *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p = '\0'; +} +#endif diff --git a/openssh/sshbuf-getput-basic.c b/openssh/sshbuf-getput-basic.c new file mode 100644 index 0000000..b7d0758 --- /dev/null +++ b/openssh/sshbuf-getput-basic.c @@ -0,0 +1,421 @@ +/* $OpenBSD: sshbuf-getput-basic.c,v 1.1 2014/04/30 05:29:56 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. + */ + +#define SSHBUF_INTERNAL +#include "includes.h" + +#include +#include +#include +#include + +#include "ssherr.h" +#include "sshbuf.h" + +int +sshbuf_get(struct sshbuf *buf, void *v, size_t len) +{ + const u_char *p = sshbuf_ptr(buf); + int r; + + if ((r = sshbuf_consume(buf, len)) < 0) + return r; + if (v != NULL) + memcpy(v, p, len); + return 0; +} + +int +sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp) +{ + const u_char *p = sshbuf_ptr(buf); + int r; + + if ((r = sshbuf_consume(buf, 8)) < 0) + return r; + if (valp != NULL) + *valp = PEEK_U64(p); + return 0; +} + +int +sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp) +{ + const u_char *p = sshbuf_ptr(buf); + int r; + + if ((r = sshbuf_consume(buf, 4)) < 0) + return r; + if (valp != NULL) + *valp = PEEK_U32(p); + return 0; +} + +int +sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp) +{ + const u_char *p = sshbuf_ptr(buf); + int r; + + if ((r = sshbuf_consume(buf, 2)) < 0) + return r; + if (valp != NULL) + *valp = PEEK_U16(p); + return 0; +} + +int +sshbuf_get_u8(struct sshbuf *buf, u_char *valp) +{ + const u_char *p = sshbuf_ptr(buf); + int r; + + if ((r = sshbuf_consume(buf, 1)) < 0) + return r; + if (valp != NULL) + *valp = (u_int8_t)*p; + return 0; +} + +int +sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) +{ + const u_char *val; + size_t len; + int r; + + if (valp != NULL) + *valp = NULL; + if (lenp != NULL) + *lenp = 0; + if ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0) + return r; + if (valp != NULL) { + if ((*valp = malloc(len + 1)) == NULL) { + SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); + return SSH_ERR_ALLOC_FAIL; + } + memcpy(*valp, val, len); + (*valp)[len] = '\0'; + } + if (lenp != NULL) + *lenp = len; + return 0; +} + +int +sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp) +{ + size_t len; + const u_char *p; + int r; + + if (valp != NULL) + *valp = NULL; + if (lenp != NULL) + *lenp = 0; + if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0) + return r; + if (valp != 0) + *valp = p; + if (lenp != NULL) + *lenp = len; + if (sshbuf_consume(buf, len + 4) != 0) { + /* Shouldn't happen */ + SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); + SSHBUF_ABORT(); + return SSH_ERR_INTERNAL_ERROR; + } + return 0; +} + +int +sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, + size_t *lenp) +{ + u_int32_t len; + const u_char *p = sshbuf_ptr(buf); + + if (valp != NULL) + *valp = NULL; + if (lenp != NULL) + *lenp = 0; + if (sshbuf_len(buf) < 4) { + SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); + return SSH_ERR_MESSAGE_INCOMPLETE; + } + len = PEEK_U32(p); + if (len > SSHBUF_SIZE_MAX - 4) { + SSHBUF_DBG(("SSH_ERR_STRING_TOO_LARGE")); + return SSH_ERR_STRING_TOO_LARGE; + } + if (sshbuf_len(buf) - 4 < len) { + SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); + return SSH_ERR_MESSAGE_INCOMPLETE; + } + if (valp != 0) + *valp = p + 4; + if (lenp != NULL) + *lenp = len; + return 0; +} + +int +sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp) +{ + size_t len; + const u_char *p, *z; + int r; + + if (valp != NULL) + *valp = NULL; + if (lenp != NULL) + *lenp = 0; + if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) + return r; + /* Allow a \0 only at the end of the string */ + if (len > 0 && + (z = memchr(p , '\0', len)) != NULL && z < p + len - 1) { + SSHBUF_DBG(("SSH_ERR_INVALID_FORMAT")); + return SSH_ERR_INVALID_FORMAT; + } + if ((r = sshbuf_skip_string(buf)) != 0) + return -1; + if (valp != NULL) { + if ((*valp = malloc(len + 1)) == NULL) { + SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); + return SSH_ERR_ALLOC_FAIL; + } + memcpy(*valp, p, len); + (*valp)[len] = '\0'; + } + if (lenp != NULL) + *lenp = (size_t)len; + return 0; +} + +int +sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v) +{ + u_int32_t len; + u_char *p; + int r; + + /* + * Use sshbuf_peek_string_direct() to figure out if there is + * a complete string in 'buf' and copy the string directly + * into 'v'. + */ + if ((r = sshbuf_peek_string_direct(buf, NULL, NULL)) != 0 || + (r = sshbuf_get_u32(buf, &len)) != 0 || + (r = sshbuf_reserve(v, len, &p)) != 0 || + (r = sshbuf_get(buf, p, len)) != 0) + return r; + return 0; +} + +int +sshbuf_put(struct sshbuf *buf, const void *v, size_t len) +{ + u_char *p; + int r; + + if ((r = sshbuf_reserve(buf, len, &p)) < 0) + return r; + memcpy(p, v, len); + return 0; +} + +int +sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v) +{ + return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v)); +} + +int +sshbuf_putf(struct sshbuf *buf, const char *fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = sshbuf_putfv(buf, fmt, ap); + va_end(ap); + return r; +} + +int +sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap) +{ + va_list ap2; + int r, len; + u_char *p; + + va_copy(ap2, ap); + if ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + if (len == 0) { + r = 0; + goto out; /* Nothing to do */ + } + va_end(ap2); + va_copy(ap2, ap); + if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0) + goto out; + if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; /* Shouldn't happen */ + } + /* Consume terminating \0 */ + if ((r = sshbuf_consume_end(buf, 1)) != 0) + goto out; + r = 0; + out: + va_end(ap2); + return r; +} + +int +sshbuf_put_u64(struct sshbuf *buf, u_int64_t val) +{ + u_char *p; + int r; + + if ((r = sshbuf_reserve(buf, 8, &p)) < 0) + return r; + POKE_U64(p, val); + return 0; +} + +int +sshbuf_put_u32(struct sshbuf *buf, u_int32_t val) +{ + u_char *p; + int r; + + if ((r = sshbuf_reserve(buf, 4, &p)) < 0) + return r; + POKE_U32(p, val); + return 0; +} + +int +sshbuf_put_u16(struct sshbuf *buf, u_int16_t val) +{ + u_char *p; + int r; + + if ((r = sshbuf_reserve(buf, 2, &p)) < 0) + return r; + POKE_U16(p, val); + return 0; +} + +int +sshbuf_put_u8(struct sshbuf *buf, u_char val) +{ + u_char *p; + int r; + + if ((r = sshbuf_reserve(buf, 1, &p)) < 0) + return r; + p[0] = val; + return 0; +} + +int +sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) +{ + u_char *d; + int r; + + if (len > SSHBUF_SIZE_MAX - 4) { + SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); + return SSH_ERR_NO_BUFFER_SPACE; + } + if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0) + return r; + POKE_U32(d, len); + memcpy(d + 4, v, len); + return 0; +} + +int +sshbuf_put_cstring(struct sshbuf *buf, const char *v) +{ + return sshbuf_put_string(buf, (u_char *)v, strlen(v)); +} + +int +sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v) +{ + return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v)); +} + +int +sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp) +{ + const u_char *p; + size_t len; + struct sshbuf *ret; + int r; + + if (buf == NULL || bufp == NULL) + return SSH_ERR_INVALID_ARGUMENT; + *bufp = NULL; + if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0) + return r; + if ((ret = sshbuf_from(p, len)) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_consume(buf, len + 4)) != 0 || /* Shouldn't happen */ + (r = sshbuf_set_parent(ret, buf)) != 0) { + sshbuf_free(ret); + return r; + } + *bufp = ret; + return 0; +} + +int +sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len) +{ + u_char *d; + const u_char *s = (const u_char *)v; + int r, prepend; + + if (len > SSHBUF_SIZE_MAX - 5) { + SSHBUF_DBG(("SSH_ERR_NO_BUFFER_SPACE")); + return SSH_ERR_NO_BUFFER_SPACE; + } + /* Skip leading zero bytes */ + for (; len > 0 && *s == 0; len--, s++) + ; + /* + * If most significant bit is set then prepend a zero byte to + * avoid interpretation as a negative number. + */ + prepend = len > 0 && (s[0] & 0x80) != 0; + if ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0) + return r; + POKE_U32(d, len + prepend); + if (prepend) + d[4] = 0; + memcpy(d + 4 + prepend, s, len); + return 0; +} diff --git a/openssh/ssherr.h b/openssh/ssherr.h new file mode 100644 index 0000000..106f786 --- /dev/null +++ b/openssh/ssherr.h @@ -0,0 +1,80 @@ +/* $OpenBSD: ssherr.h,v 1.1 2014/04/30 05:29:56 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. + */ + +#ifndef _SSHERR_H +#define _SSHERR_H + +/* XXX are these too granular? not granular enough? I can't decide - djm */ + +/* Error codes */ +#define SSH_ERR_SUCCESS 0 +#define SSH_ERR_INTERNAL_ERROR -1 +#define SSH_ERR_ALLOC_FAIL -2 +#define SSH_ERR_MESSAGE_INCOMPLETE -3 +#define SSH_ERR_INVALID_FORMAT -4 +#define SSH_ERR_BIGNUM_IS_NEGATIVE -5 +#define SSH_ERR_STRING_TOO_LARGE -6 +#define SSH_ERR_BIGNUM_TOO_LARGE -7 +#define SSH_ERR_ECPOINT_TOO_LARGE -8 +#define SSH_ERR_NO_BUFFER_SPACE -9 +#define SSH_ERR_INVALID_ARGUMENT -10 +#define SSH_ERR_KEY_BITS_MISMATCH -11 +#define SSH_ERR_EC_CURVE_INVALID -12 +#define SSH_ERR_KEY_TYPE_MISMATCH -13 +#define SSH_ERR_KEY_TYPE_UNKNOWN -14 /* XXX UNSUPPORTED? */ +#define SSH_ERR_EC_CURVE_MISMATCH -15 +#define SSH_ERR_EXPECTED_CERT -16 +#define SSH_ERR_KEY_LACKS_CERTBLOB -17 +#define SSH_ERR_KEY_CERT_UNKNOWN_TYPE -18 +#define SSH_ERR_KEY_CERT_INVALID_SIGN_KEY -19 +#define SSH_ERR_KEY_INVALID_EC_VALUE -20 +#define SSH_ERR_SIGNATURE_INVALID -21 +#define SSH_ERR_LIBCRYPTO_ERROR -22 +#define SSH_ERR_UNEXPECTED_TRAILING_DATA -23 +#define SSH_ERR_SYSTEM_ERROR -24 +#define SSH_ERR_KEY_CERT_INVALID -25 +#define SSH_ERR_AGENT_COMMUNICATION -26 +#define SSH_ERR_AGENT_FAILURE -27 +#define SSH_ERR_DH_GEX_OUT_OF_RANGE -28 +#define SSH_ERR_DISCONNECTED -29 +#define SSH_ERR_MAC_INVALID -30 +#define SSH_ERR_NO_CIPHER_ALG_MATCH -31 +#define SSH_ERR_NO_MAC_ALG_MATCH -32 +#define SSH_ERR_NO_COMPRESS_ALG_MATCH -33 +#define SSH_ERR_NO_KEX_ALG_MATCH -34 +#define SSH_ERR_NO_HOSTKEY_ALG_MATCH -35 +#define SSH_ERR_NO_HOSTKEY_LOADED -36 +#define SSH_ERR_PROTOCOL_MISMATCH -37 +#define SSH_ERR_NO_PROTOCOL_VERSION -38 +#define SSH_ERR_NEED_REKEY -39 +#define SSH_ERR_PASSPHRASE_TOO_SHORT -40 +#define SSH_ERR_FILE_CHANGED -41 +#define SSH_ERR_KEY_UNKNOWN_CIPHER -42 +#define SSH_ERR_KEY_WRONG_PASSPHRASE -43 +#define SSH_ERR_KEY_BAD_PERMISSIONS -44 +#define SSH_ERR_KEY_CERT_MISMATCH -45 +#define SSH_ERR_KEY_NOT_FOUND -46 +#define SSH_ERR_AGENT_NOT_PRESENT -47 +#define SSH_ERR_AGENT_NO_IDENTITIES -48 +#define SSH_ERR_BUFFER_READ_ONLY -49 +#define SSH_ERR_KRL_BAD_MAGIC -50 +#define SSH_ERR_KEY_REVOKED -51 + +/* Translate a numeric error code to a human-readable error string */ +const char *ssh_err(int n); + +#endif /* _SSHERR_H */ diff --git a/openssh/xmalloc.h b/openssh/xmalloc.h new file mode 100644 index 0000000..261dfd6 --- /dev/null +++ b/openssh/xmalloc.h @@ -0,0 +1,25 @@ +/* $OpenBSD: xmalloc.h,v 1.14 2013/05/17 00:13:14 djm Exp $ */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Created: Mon Mar 20 22:09:17 1995 ylo + * + * Versions of malloc and friends that check their results, and never return + * failure (they call fatal if they encounter an error). + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +void *xmalloc(size_t); +void *xcalloc(size_t, size_t); +void *xrealloc(void *, size_t, size_t); +char *xstrdup(const char *); +int xasprintf(char **, const char *, ...) + __attribute__((__format__ (printf, 2, 3))) + __attribute__((__nonnull__ (2)));