these should also be stock files from openssh 6.7p1, and represent all of

the ones that I had to modify to get sftp-server to build
sigsegv_dump
Greg Alexander 9 years ago
parent 36d9710042
commit 19bc9f19f5

@ -0,0 +1,259 @@
/* $OpenBSD: bufaux.c,v 1.60 2014/04/30 05:29:56 djm Exp $ */
/*
* Copyright (c) 2012 Damien Miller <djm@mindrot.org>
*
* 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.
*/
/* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */
#include "includes.h"
#include <sys/types.h>
#include "buffer.h"
#include "log.h"
#include "ssherr.h"
int
buffer_get_short_ret(u_short *v, Buffer *buffer)
{
int ret;
if ((ret = sshbuf_get_u16(buffer, v)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
u_short
buffer_get_short(Buffer *buffer)
{
u_short ret;
if (buffer_get_short_ret(&ret, buffer) == -1)
fatal("%s: buffer error", __func__);
return (ret);
}
int
buffer_get_int_ret(u_int *v, Buffer *buffer)
{
int ret;
if ((ret = sshbuf_get_u32(buffer, v)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
u_int
buffer_get_int(Buffer *buffer)
{
u_int ret;
if (buffer_get_int_ret(&ret, buffer) == -1)
fatal("%s: buffer error", __func__);
return (ret);
}
int
buffer_get_int64_ret(u_int64_t *v, Buffer *buffer)
{
int ret;
if ((ret = sshbuf_get_u64(buffer, v)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
u_int64_t
buffer_get_int64(Buffer *buffer)
{
u_int64_t ret;
if (buffer_get_int64_ret(&ret, buffer) == -1)
fatal("%s: buffer error", __func__);
return (ret);
}
void
buffer_put_short(Buffer *buffer, u_short value)
{
int ret;
if ((ret = sshbuf_put_u16(buffer, value)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_put_int(Buffer *buffer, u_int value)
{
int ret;
if ((ret = sshbuf_put_u32(buffer, value)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_put_int64(Buffer *buffer, u_int64_t value)
{
int ret;
if ((ret = sshbuf_put_u64(buffer, value)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void *
buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
{
size_t len;
int ret;
u_char *value;
if ((ret = sshbuf_get_string(buffer, &value, &len)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return NULL;
}
if (length_ptr != NULL)
*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */
return value;
}
void *
buffer_get_string(Buffer *buffer, u_int *length_ptr)
{
void *ret;
if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)
fatal("%s: buffer error", __func__);
return (ret);
}
char *
buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
{
size_t len;
int ret;
char *value;
if ((ret = sshbuf_get_cstring(buffer, &value, &len)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return NULL;
}
if (length_ptr != NULL)
*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */
return value;
}
char *
buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
{
char *ret;
if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
fatal("%s: buffer error", __func__);
return ret;
}
const void *
buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
{
size_t len;
int ret;
const u_char *value;
if ((ret = sshbuf_get_string_direct(buffer, &value, &len)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return NULL;
}
if (length_ptr != NULL)
*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */
return value;
}
const void *
buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
{
const void *ret;
if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL)
fatal("%s: buffer error", __func__);
return (ret);
}
void
buffer_put_string(Buffer *buffer, const void *buf, u_int len)
{
int ret;
if ((ret = sshbuf_put_string(buffer, buf, len)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_put_cstring(Buffer *buffer, const char *s)
{
int ret;
if ((ret = sshbuf_put_cstring(buffer, s)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
int
buffer_get_char_ret(char *v, Buffer *buffer)
{
int ret;
if ((ret = sshbuf_get_u8(buffer, (u_char *)v)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
int
buffer_get_char(Buffer *buffer)
{
char ch;
if (buffer_get_char_ret(&ch, buffer) == -1)
fatal("%s: buffer error", __func__);
return (u_char) ch;
}
void
buffer_put_char(Buffer *buffer, int value)
{
int ret;
if ((ret = sshbuf_put_u8(buffer, value)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)
{
int ret;
if ((ret = sshbuf_put_bignum2_bytes(buffer, s, l)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}

@ -0,0 +1,118 @@
/* $OpenBSD: buffer.c,v 1.36 2014/04/30 05:29:56 djm Exp $ */
/*
* Copyright (c) 2012 Damien Miller <djm@mindrot.org>
*
* 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.
*/
/* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */
#include "includes.h"
#include <sys/types.h>
#include "buffer.h"
#include "log.h"
#include "ssherr.h"
void
buffer_append(Buffer *buffer, const void *data, u_int len)
{
int ret;
if ((ret = sshbuf_put(buffer, data, len)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
}
void *
buffer_append_space(Buffer *buffer, u_int len)
{
int ret;
u_char *p;
if ((ret = sshbuf_reserve(buffer, len, &p)) != 0)
fatal("%s: %s", __func__, ssh_err(ret));
return p;
}
int
buffer_check_alloc(Buffer *buffer, u_int len)
{
int ret = sshbuf_check_reserve(buffer, len);
if (ret == 0)
return 1;
if (ret == SSH_ERR_NO_BUFFER_SPACE)
return 0;
fatal("%s: %s", __func__, ssh_err(ret));
}
int
buffer_get_ret(Buffer *buffer, void *buf, u_int len)
{
int ret;
if ((ret = sshbuf_get(buffer, buf, len)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
void
buffer_get(Buffer *buffer, void *buf, u_int len)
{
if (buffer_get_ret(buffer, buf, len) == -1)
fatal("%s: buffer error", __func__);
}
int
buffer_consume_ret(Buffer *buffer, u_int bytes)
{
int ret = sshbuf_consume(buffer, bytes);
if (ret == 0)
return 0;
if (ret == SSH_ERR_MESSAGE_INCOMPLETE)
return -1;
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_consume(Buffer *buffer, u_int bytes)
{
if (buffer_consume_ret(buffer, bytes) == -1)
fatal("%s: buffer error", __func__);
}
int
buffer_consume_end_ret(Buffer *buffer, u_int bytes)
{
int ret = sshbuf_consume_end(buffer, bytes);
if (ret == 0)
return 0;
if (ret == SSH_ERR_MESSAGE_INCOMPLETE)
return -1;
fatal("%s: %s", __func__, ssh_err(ret));
}
void
buffer_consume_end(Buffer *buffer, u_int bytes)
{
if (buffer_consume_end_ret(buffer, bytes) == -1)
fatal("%s: buffer error", __func__);
}

@ -0,0 +1,844 @@
/*
* Copyright (c) 1999-2003 Damien Miller. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _DEFINES_H
#define _DEFINES_H
/* $Id: defines.h,v 1.183 2014/09/02 19:33:26 djm Exp $ */
/* Constants */
#if defined(HAVE_DECL_SHUT_RD) && HAVE_DECL_SHUT_RD == 0
enum
{
SHUT_RD = 0, /* No more receptions. */
SHUT_WR, /* No more transmissions. */
SHUT_RDWR /* No more receptions or transmissions. */
};
# define SHUT_RD SHUT_RD
# define SHUT_WR SHUT_WR
# define SHUT_RDWR SHUT_RDWR
#endif
/*
* Definitions for IP type of service (ip_tos)
*/
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifndef IPTOS_LOWDELAY
# define IPTOS_LOWDELAY 0x10
# define IPTOS_THROUGHPUT 0x08
# define IPTOS_RELIABILITY 0x04
# define IPTOS_LOWCOST 0x02
# define IPTOS_MINCOST IPTOS_LOWCOST
#endif /* IPTOS_LOWDELAY */
/*
* Definitions for DiffServ Codepoints as per RFC2474
*/
#ifndef IPTOS_DSCP_AF11
# define IPTOS_DSCP_AF11 0x28
# define IPTOS_DSCP_AF12 0x30
# define IPTOS_DSCP_AF13 0x38
# define IPTOS_DSCP_AF21 0x48
# define IPTOS_DSCP_AF22 0x50
# define IPTOS_DSCP_AF23 0x58
# define IPTOS_DSCP_AF31 0x68
# define IPTOS_DSCP_AF32 0x70
# define IPTOS_DSCP_AF33 0x78
# define IPTOS_DSCP_AF41 0x88
# define IPTOS_DSCP_AF42 0x90
# define IPTOS_DSCP_AF43 0x98
# define IPTOS_DSCP_EF 0xb8
#endif /* IPTOS_DSCP_AF11 */
#ifndef IPTOS_DSCP_CS0
# define IPTOS_DSCP_CS0 0x00
# define IPTOS_DSCP_CS1 0x20
# define IPTOS_DSCP_CS2 0x40
# define IPTOS_DSCP_CS3 0x60
# define IPTOS_DSCP_CS4 0x80
# define IPTOS_DSCP_CS5 0xa0
# define IPTOS_DSCP_CS6 0xc0
# define IPTOS_DSCP_CS7 0xe0
#endif /* IPTOS_DSCP_CS0 */
#ifndef IPTOS_DSCP_EF
# define IPTOS_DSCP_EF 0xb8
#endif /* IPTOS_DSCP_EF */
#ifndef PATH_MAX
# ifdef _POSIX_PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
# endif
#endif
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# else /* PATH_MAX */
# define MAXPATHLEN 64
/* realpath uses a fixed buffer of size MAXPATHLEN, so force use of ours */
# ifndef BROKEN_REALPATH
# define BROKEN_REALPATH 1
# endif /* BROKEN_REALPATH */
# endif /* PATH_MAX */
#endif /* MAXPATHLEN */
#if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0
# define MAXSYMLINKS 5
#endif
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
# define STDERR_FILENO 2
#endif
#ifndef NGROUPS_MAX /* Disable groupaccess if NGROUP_MAX is not set */
#ifdef NGROUPS
#define NGROUPS_MAX NGROUPS
#else
#define NGROUPS_MAX 0
#endif
#endif
#if defined(HAVE_DECL_O_NONBLOCK) && HAVE_DECL_O_NONBLOCK == 0
# define O_NONBLOCK 00004 /* Non Blocking Open */
#endif
#ifndef S_IFSOCK
# define S_IFSOCK 0
#endif /* S_IFSOCK */
#ifndef S_ISDIR
# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
#endif /* S_ISDIR */
#ifndef S_ISREG
# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
#endif /* S_ISREG */
#ifndef S_ISLNK
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif /* S_ISLNK */
#ifndef S_IXUSR
# define S_IXUSR 0000100 /* execute/search permission, */
# define S_IXGRP 0000010 /* execute/search permission, */
# define S_IXOTH 0000001 /* execute/search permission, */
# define _S_IWUSR 0000200 /* write permission, */
# define S_IWUSR _S_IWUSR /* write permission, owner */
# define S_IWGRP 0000020 /* write permission, group */
# define S_IWOTH 0000002 /* write permission, other */
# define S_IRUSR 0000400 /* read permission, owner */
# define S_IRGRP 0000040 /* read permission, group */
# define S_IROTH 0000004 /* read permission, other */
# define S_IRWXU 0000700 /* read, write, execute */
# define S_IRWXG 0000070 /* read, write, execute */
# define S_IRWXO 0000007 /* read, write, execute */
#endif /* S_IXUSR */
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
#define MAP_ANON MAP_ANONYMOUS
#endif
#ifndef MAP_FAILED
# define MAP_FAILED ((void *)-1)
#endif
/*
SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but
including rpc/rpc.h breaks Solaris 6
*/
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK ((u_long)0x7f000001)
#endif
/* Types */
/* If sys/types.h does not supply intXX_t, supply them ourselves */
/* (or die trying) */
#ifndef HAVE_U_INT
typedef unsigned int u_int;
#endif
#ifndef HAVE_INTXX_T
typedef signed char int8_t;
# if (SIZEOF_SHORT_INT == 2)
typedef short int int16_t;
# else
# ifdef _UNICOS
# if (SIZEOF_SHORT_INT == 4)
typedef short int16_t;
# else
typedef long int16_t;
# endif
# else
# error "16 bit int type not found."
# endif /* _UNICOS */
# endif
# if (SIZEOF_INT == 4)
typedef int int32_t;
# else
# ifdef _UNICOS
typedef long int32_t;
# else
# error "32 bit int type not found."
# endif /* _UNICOS */
# endif
#endif
/* If sys/types.h does not supply u_intXX_t, supply them ourselves */
#ifndef HAVE_U_INTXX_T
# ifdef HAVE_UINTXX_T
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
# define HAVE_U_INTXX_T 1
# else
typedef unsigned char u_int8_t;
# if (SIZEOF_SHORT_INT == 2)
typedef unsigned short int u_int16_t;
# else
# ifdef _UNICOS
# if (SIZEOF_SHORT_INT == 4)
typedef unsigned short u_int16_t;
# else
typedef unsigned long u_int16_t;
# endif
# else
# error "16 bit int type not found."
# endif
# endif
# if (SIZEOF_INT == 4)
typedef unsigned int u_int32_t;
# else
# ifdef _UNICOS
typedef unsigned long u_int32_t;
# else
# error "32 bit int type not found."
# endif
# endif
# endif
#define __BIT_TYPES_DEFINED__
#endif
/* 64-bit types */
#ifndef HAVE_INT64_T
# if (SIZEOF_LONG_INT == 8)
typedef long int int64_t;
# else
# if (SIZEOF_LONG_LONG_INT == 8)
typedef long long int int64_t;
# endif
# endif
#endif
#ifndef HAVE_U_INT64_T
# if (SIZEOF_LONG_INT == 8)
typedef unsigned long int u_int64_t;
# else
# if (SIZEOF_LONG_LONG_INT == 8)
typedef unsigned long long int u_int64_t;
# endif
# endif
#endif
#ifndef HAVE_UINTXX_T
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
#endif
#ifndef HAVE_INTMAX_T
typedef long long intmax_t;
#endif
#ifndef HAVE_UINTMAX_T
typedef unsigned long long uintmax_t;
#endif
#ifndef HAVE_U_CHAR
typedef unsigned char u_char;
# define HAVE_U_CHAR
#endif /* HAVE_U_CHAR */
#ifndef ULLONG_MAX
# define ULLONG_MAX ((unsigned long long)-1)
#endif
#ifndef SIZE_T_MAX
#define SIZE_T_MAX ULONG_MAX
#endif /* SIZE_T_MAX */
#ifndef HAVE_SIZE_T
typedef unsigned int size_t;
# define HAVE_SIZE_T
# define SIZE_T_MAX UINT_MAX
#endif /* HAVE_SIZE_T */
#ifndef SIZE_MAX
#define SIZE_MAX SIZE_T_MAX
#endif
#ifndef HAVE_SSIZE_T
typedef int ssize_t;
# define HAVE_SSIZE_T
#endif /* HAVE_SSIZE_T */
#ifndef HAVE_CLOCK_T
typedef long clock_t;
# define HAVE_CLOCK_T
#endif /* HAVE_CLOCK_T */
#ifndef HAVE_SA_FAMILY_T
typedef int sa_family_t;
# define HAVE_SA_FAMILY_T
#endif /* HAVE_SA_FAMILY_T */
#ifndef HAVE_PID_T
typedef int pid_t;
# define HAVE_PID_T
#endif /* HAVE_PID_T */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
# define HAVE_SIG_ATOMIC_T
#endif /* HAVE_SIG_ATOMIC_T */
#ifndef HAVE_MODE_T
typedef int mode_t;
# define HAVE_MODE_T
#endif /* HAVE_MODE_T */
#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS)
# define ss_family __ss_family
#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */
#ifndef HAVE_SYS_UN_H
struct sockaddr_un {
short sun_family; /* AF_UNIX */
char sun_path[108]; /* path name (gag) */
};
#endif /* HAVE_SYS_UN_H */
#ifndef HAVE_IN_ADDR_T
typedef u_int32_t in_addr_t;
#endif
#ifndef HAVE_IN_PORT_T
typedef u_int16_t in_port_t;
#endif
#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
#define _STRUCT_WINSIZE
struct winsize {
unsigned short ws_row; /* rows, in characters */
unsigned short ws_col; /* columns, in character */
unsigned short ws_xpixel; /* horizontal size, pixels */
unsigned short ws_ypixel; /* vertical size, pixels */
};
#endif
/* bits needed for select that may not be in the system headers */
#ifndef HAVE_FD_MASK
typedef unsigned long int fd_mask;
#endif
#if defined(HAVE_DECL_NFDBITS) && HAVE_DECL_NFDBITS == 0
# define NFDBITS (8 * sizeof(unsigned long))
#endif
#if defined(HAVE_DECL_HOWMANY) && HAVE_DECL_HOWMANY == 0
# define howmany(x,y) (((x)+((y)-1))/(y))
#endif
/* Paths */
#ifndef _PATH_BSHELL
# define _PATH_BSHELL "/bin/sh"
#endif
#ifdef USER_PATH
# ifdef _PATH_STDPATH
# undef _PATH_STDPATH
# endif
# define _PATH_STDPATH USER_PATH
#endif
#ifndef _PATH_STDPATH
# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
#endif
#ifndef SUPERUSER_PATH
# define SUPERUSER_PATH _PATH_STDPATH
#endif
#ifndef _PATH_DEVNULL
# define _PATH_DEVNULL "/dev/null"
#endif
/* user may have set a different path */
#if defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY)
# undef _PATH_MAILDIR
#endif /* defined(_PATH_MAILDIR) && defined(MAIL_DIRECTORY) */
#ifdef MAIL_DIRECTORY
# define _PATH_MAILDIR MAIL_DIRECTORY
#endif
#ifndef _PATH_NOLOGIN
# define _PATH_NOLOGIN "/etc/nologin"
#endif
/* Define this to be the path of the xauth program. */
#ifdef XAUTH_PATH
#define _PATH_XAUTH XAUTH_PATH
#endif /* XAUTH_PATH */
/* derived from XF4/xc/lib/dps/Xlibnet.h */
#ifndef X_UNIX_PATH
# ifdef __hpux
# define X_UNIX_PATH "/var/spool/sockets/X11/%u"
# else
# define X_UNIX_PATH "/tmp/.X11-unix/X%u"
# endif
#endif /* X_UNIX_PATH */
#define _PATH_UNIX_X X_UNIX_PATH
#ifndef _PATH_TTY
# define _PATH_TTY "/dev/tty"
#endif
/* Macros */
#if defined(HAVE_LOGIN_GETCAPBOOL) && defined(HAVE_LOGIN_CAP_H)
# define HAVE_LOGIN_CAP
#endif
#ifndef MAX
# define MAX(a,b) (((a)>(b))?(a):(b))
# define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef roundup
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
#endif
#ifndef timersub
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
#ifndef TIMEVAL_TO_TIMESPEC
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
}
#endif
#ifndef TIMESPEC_TO_TIMEVAL
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
}
#endif
#ifndef __P
# define __P(x) x
#endif
#if !defined(IN6_IS_ADDR_V4MAPPED)
# define IN6_IS_ADDR_V4MAPPED(a) \
((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
(((u_int32_t *) (a))[2] == htonl (0xffff)))
#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */
#if !defined(__GNUC__) || (__GNUC__ < 2)
# define __attribute__(x)
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
#if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__)
# define __sentinel__
#endif
#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__)
# define __bounded__(x, y, z)
#endif
#if !defined(HAVE_ATTRIBUTE__NONNULL__) && !defined(__nonnull__)
# define __nonnull__(x)
#endif
#ifndef OSSH_ALIGNBYTES
#define OSSH_ALIGNBYTES (sizeof(int) - 1)
#endif
#ifndef __CMSG_ALIGN
#define __CMSG_ALIGN(p) (((u_int)(p) + OSSH_ALIGNBYTES) &~ OSSH_ALIGNBYTES)
#endif
/* Length of the contents of a control message of length len */
#ifndef CMSG_LEN
#define CMSG_LEN(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
#endif
/* Length of the space taken up by a padded control message of length len */
#ifndef CMSG_SPACE
#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len))
#endif
/* given pointer to struct cmsghdr, return pointer to data */
#ifndef CMSG_DATA
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr)))
#endif /* CMSG_DATA */
/*
* RFC 2292 requires to check msg_controllen, in case that the kernel returns
* an empty list for some reasons.
*/
#ifndef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
(struct cmsghdr *)NULL)
#endif /* CMSG_FIRSTHDR */
#if defined(HAVE_DECL_OFFSETOF) && HAVE_DECL_OFFSETOF == 0
# define offsetof(type, member) ((size_t) &((type *)0)->member)
#endif
/* Set up BSD-style BYTE_ORDER definition if it isn't there already */
/* XXX: doesn't try to cope with strange byte orders (PDP_ENDIAN) */
#ifndef BYTE_ORDER
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN 1234
# endif /* LITTLE_ENDIAN */
# ifndef BIG_ENDIAN
# define BIG_ENDIAN 4321
# endif /* BIG_ENDIAN */
# ifdef WORDS_BIGENDIAN
# define BYTE_ORDER BIG_ENDIAN
# else /* WORDS_BIGENDIAN */
# define BYTE_ORDER LITTLE_ENDIAN
# endif /* WORDS_BIGENDIAN */
#endif /* BYTE_ORDER */
/* Function replacement / compatibility hacks */
#if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO))
# define HAVE_GETADDRINFO
#endif
#ifndef HAVE_GETOPT_OPTRESET
# undef getopt
# undef opterr
# undef optind
# undef optopt
# undef optreset
# undef optarg
# define getopt(ac, av, o) BSDgetopt(ac, av, o)
# define opterr BSDopterr
# define optind BSDoptind
# define optopt BSDoptopt
# define optreset BSDoptreset
# define optarg BSDoptarg
#endif
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO)
# undef HAVE_GETADDRINFO
#endif
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO)
# undef HAVE_FREEADDRINFO
#endif
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR)
# undef HAVE_GAI_STRERROR
#endif
#if defined(BROKEN_UPDWTMPX) && defined(HAVE_UPDWTMPX)
# undef HAVE_UPDWTMPX
#endif
#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE)
# undef HAS_SHADOW_EXPIRE
#endif
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
defined(SYSLOG_R_SAFE_IN_SIGHAND)
# define DO_LOG_SAFE_IN_SIGHAND
#endif
#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
# define memmove(s1, s2, n) bcopy((s2), (s1), (n))
#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */
#ifndef GETPGRP_VOID
# include <unistd.h>
# define getpgrp() getpgrp(0)
#endif
#ifdef USE_BSM_AUDIT
# define SSH_AUDIT_EVENTS
# define CUSTOM_SSH_AUDIT_EVENTS
#endif
#ifdef USE_LINUX_AUDIT
# define SSH_AUDIT_EVENTS
# define CUSTOM_SSH_AUDIT_EVENTS
#endif
#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
# define __func__ __FUNCTION__
#elif !defined(HAVE___func__)
# define __func__ ""
#endif
#if defined(KRB5) && !defined(HEIMDAL)
# define krb5_get_err_text(context,code) error_message(code)
#endif
#if defined(SKEYCHALLENGE_4ARG)
# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c,d)
#else
# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c)
#endif
/* Maximum number of file descriptors available */
#ifdef HAVE_SYSCONF
# define SSH_SYSFDMAX sysconf(_SC_OPEN_MAX)
#else
# define SSH_SYSFDMAX 10000
#endif
#ifdef FSID_HAS_VAL
/* encode f_fsid into a 64 bit value */
#define FSID_TO_ULONG(f) \
((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
((f).val[1] & 0xffffffffUL))
#elif defined(FSID_HAS___VAL)
#define FSID_TO_ULONG(f) \
((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \
((f).__val[1] & 0xffffffffUL))
#else
# define FSID_TO_ULONG(f) ((f))
#endif
#if defined(__Lynx__)
/*
* LynxOS defines these in param.h which we do not want to include since
* it will also pull in a bunch of kernel definitions.
*/
# define ALIGNBYTES (sizeof(int) - 1)
# define ALIGN(p) (((unsigned)p + ALIGNBYTES) & ~ALIGNBYTES)
/* Missing prototypes on LynxOS */
int snprintf (char *, size_t, const char *, ...);
int mkstemp (char *);
char *crypt (const char *, const char *);
int seteuid (uid_t);
int setegid (gid_t);
char *mkdtemp (char *);
int rresvport_af (int *, sa_family_t);
int innetgr (const char *, const char *, const char *, const char *);
#endif
/*
* Define this to use pipes instead of socketpairs for communicating with the
* client program. Socketpairs do not seem to work on all systems.
*
* configure.ac sets this for a few OS's which are known to have problems
* but you may need to set it yourself
*/
/* #define USE_PIPES 1 */
/**
** login recorder definitions
**/
/* FIXME: put default paths back in */
#ifndef UTMP_FILE
# ifdef _PATH_UTMP
# define UTMP_FILE _PATH_UTMP
# else
# ifdef CONF_UTMP_FILE
# define UTMP_FILE CONF_UTMP_FILE
# endif
# endif
#endif
#ifndef WTMP_FILE
# ifdef _PATH_WTMP
# define WTMP_FILE _PATH_WTMP
# else
# ifdef CONF_WTMP_FILE
# define WTMP_FILE CONF_WTMP_FILE
# endif
# endif
#endif
/* pick up the user's location for lastlog if given */
#ifndef LASTLOG_FILE
# ifdef _PATH_LASTLOG
# define LASTLOG_FILE _PATH_LASTLOG
# else
# ifdef CONF_LASTLOG_FILE
# define LASTLOG_FILE CONF_LASTLOG_FILE
# endif
# endif
#endif
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
# define USE_SHADOW
#endif
/* The login() library function in libutil is first choice */
#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN)
# define USE_LOGIN
#else
/* Simply select your favourite login types. */
/* Can't do if-else because some systems use several... <sigh> */
# if !defined(DISABLE_UTMPX)
# define USE_UTMPX
# endif
# if defined(UTMP_FILE) && !defined(DISABLE_UTMP)
# define USE_UTMP
# endif
# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX)
# define USE_WTMPX
# endif
# if defined(WTMP_FILE) && !defined(DISABLE_WTMP)
# define USE_WTMP
# endif
#endif
#ifndef UT_LINESIZE
# define UT_LINESIZE 8
#endif
/* I hope that the presence of LASTLOG_FILE is enough to detect this */
#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG)
# define USE_LASTLOG
#endif
#ifdef HAVE_OSF_SIA
# ifdef USE_SHADOW
# undef USE_SHADOW
# endif
# define CUSTOM_SYS_AUTH_PASSWD 1
#endif
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE)
# define CUSTOM_SYS_AUTH_PASSWD 1
#endif
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
# define USE_LIBIAF
#endif
/* HP-UX 11.11 */
#ifdef BTMP_FILE
# define _PATH_BTMP BTMP_FILE
#endif
#if defined(USE_BTMP) && defined(_PATH_BTMP)
# define CUSTOM_FAILED_LOGIN
#endif
/** end of login recorder definitions */
#ifdef BROKEN_GETGROUPS
# define getgroups(a,b) ((a)==0 && (b)==NULL ? NGROUPS_MAX : getgroups((a),(b)))
#endif
#if defined(HAVE_MMAP) && defined(BROKEN_MMAP)
# undef HAVE_MMAP
#endif
#ifndef IOV_MAX
# if defined(_XOPEN_IOV_MAX)
# define IOV_MAX _XOPEN_IOV_MAX
# elif defined(DEF_IOV_MAX)
# define IOV_MAX DEF_IOV_MAX
# else
# define IOV_MAX 16
# endif
#endif
#ifndef EWOULDBLOCK
# define EWOULDBLOCK EAGAIN
#endif
#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */
#define INET6_ADDRSTRLEN 46
#endif
#ifndef SSH_IOBUFSZ
# define SSH_IOBUFSZ 8192
#endif
#ifndef _NSIG
# ifdef NSIG
# define _NSIG NSIG
# else
# define _NSIG 128
# endif
#endif
/*
* Platforms that have arc4random_uniform() and not arc4random_stir()
* shouldn't need the latter.
*/
#if defined(HAVE_ARC4RANDOM) && defined(HAVE_ARC4RANDOM_UNIFORM) && \
!defined(HAVE_ARC4RANDOM_STIR)
# define arc4random_stir()
#endif
#ifndef HAVE_VA_COPY
# ifdef HAVE___VA_COPY
# define va_copy(dest, src) __va_copy(dest, src)
# else
# define va_copy(dest, src) (dest) = (src)
# endif
#endif
#ifndef __predict_true
# if defined(__GNUC__) && \
((__GNUC__ > (2)) || (__GNUC__ == (2) && __GNUC_MINOR__ >= (96)))
# define __predict_true(exp) __builtin_expect(((exp) != 0), 1)
# define __predict_false(exp) __builtin_expect(((exp) != 0), 0)
# else
# define __predict_true(exp) ((exp) != 0)
# define __predict_false(exp) ((exp) != 0)
# endif /* gcc version */
#endif /* __predict_true */
#endif /* _DEFINES_H */

@ -0,0 +1,177 @@
/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* This file includes most of the needed system headers.
*
* 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 INCLUDES_H
#define INCLUDES_H
#include "config.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* activate extra prototypes for glibc */
#endif
#include <sys/types.h>
#include <sys/socket.h> /* For CMSG_* */
#ifdef HAVE_LIMITS_H
# include <limits.h> /* For PATH_MAX */
#endif
#ifdef HAVE_BSTRING_H
# include <bstring.h>
#endif
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \
defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \
!defined(BROKEN_GLOB)
# include <glob.h>
#endif
#ifdef HAVE_ENDIAN_H
# include <endian.h>
#endif
#ifdef HAVE_TTYENT_H
# include <ttyent.h>
#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#endif
#ifdef HAVE_MAILLOCK_H
# include <maillock.h> /* For _PATH_MAILDIR */
#endif
#ifdef HAVE_NEXT
# include <libc.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
/*
*-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively
*/
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_LOGIN_H
# include <login.h>
#endif
#ifdef HAVE_UTMP_H
# include <utmp.h>
#endif
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
#endif
#ifdef HAVE_LASTLOG_H
# include <lastlog.h>
#endif
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_SYS_BSDTTY_H
# include <sys/bsdtty.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <termios.h>
#ifdef HAVE_SYS_BITYPES_H
# include <sys/bitypes.h> /* For u_intXX_t */
#endif
#ifdef HAVE_SYS_CDEFS_H
# include <sys/cdefs.h> /* For __P() */
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h> /* For S_* constants and macros */
#endif
#ifdef HAVE_SYS_SYSMACROS_H
# include <sys/sysmacros.h> /* For MIN, MAX, etc */
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h> /* for MAP_ANONYMOUS */
#endif
#ifdef HAVE_SYS_STRTIO_H
#include <sys/strtio.h> /* for TIOCCBRK on HP-UX */
#endif
#if defined(HAVE_SYS_PTMS_H) && defined(HAVE_DEV_PTMX)
# if defined(HAVE_SYS_STREAM_H)
# include <sys/stream.h> /* reqd for queue_t on Solaris 2.5.1 */
# endif
#include <sys/ptms.h> /* for grantpt() and friends */
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h> /* For typedefs */
#ifdef HAVE_RPC_TYPES_H
# include <rpc/types.h> /* For INADDR_LOOPBACK */
#endif
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
# include <security/pam_appl.h>
#elif defined (HAVE_PAM_PAM_APPL_H)
# include <pam/pam_appl.h>
#endif
#endif
#ifdef HAVE_READPASSPHRASE_H
# include <readpassphrase.h>
#endif
#ifdef HAVE_IA_H
# include <ia.h>
#endif
#ifdef HAVE_IAF_H
# include <iaf.h>
#endif
#ifdef HAVE_TMPDIR_H
# include <tmpdir.h>
#endif
#if defined(HAVE_BSD_LIBUTIL_H)
# include <bsd/libutil.h>
#elif defined(HAVE_LIBUTIL_H)
# include <libutil.h>
#endif
#if defined(KRB5) && defined(USE_AFS)
# include <krb5.h>
# include <kafs.h>
#endif
#if defined(HAVE_SYS_SYSLOG_H)
# include <sys/syslog.h>
#endif
#include <errno.h>
/*
* On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations
* of getspnam when _INCLUDE__STDC__ is defined, so we unset it here.
*/
#ifdef GETSPNAM_CONFLICTING_DEFS
# ifdef _INCLUDE__STDC__
# undef _INCLUDE__STDC__
# endif
#endif
#include "defines.h"
#include "platform.h"
#include "openbsd-compat/openbsd-compat.h"
#include "openbsd-compat/bsd-nextstep.h"
#include "entropy.h"
#endif /* INCLUDES_H */

@ -0,0 +1,279 @@
/* $OpenBSD: match.c,v 1.29 2013/11/20 20:54:10 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Simple pattern matching, with '*' and '?' as wildcards.
*
* 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".
*/
/*
* Copyright (c) 2000 Markus Friedl. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#include "includes.h"
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "match.h"
/*
* Returns true if the given string matches the pattern (which may contain ?
* and * as wildcards), and zero if it does not match.
*/
int
match_pattern(const char *s, const char *pattern)
{
for (;;) {
/* If at end of pattern, accept if also at end of string. */
if (!*pattern)
return !*s;
if (*pattern == '*') {
/* Skip the asterisk. */
pattern++;
/* If at end of pattern, accept immediately. */
if (!*pattern)
return 1;
/* If next character in pattern is known, optimize. */
if (*pattern != '?' && *pattern != '*') {
/*
* Look instances of the next character in
* pattern, and try to match starting from
* those.
*/
for (; *s; s++)
if (*s == *pattern &&
match_pattern(s + 1, pattern + 1))
return 1;
/* Failed. */
return 0;
}
/*
* Move ahead one character at a time and try to
* match at each position.
*/
for (; *s; s++)
if (match_pattern(s, pattern))
return 1;
/* Failed. */
return 0;
}
/*
* There must be at least one more character in the string.
* If we are at the end, fail.
*/
if (!*s)
return 0;
/* Check if the next character of the string is acceptable. */
if (*pattern != '?' && *pattern != *s)
return 0;
/* Move to the next character, both in string and in pattern. */
s++;
pattern++;
}
/* NOTREACHED */
}
/*
* Tries to match the string against the
* comma-separated sequence of subpatterns (each possibly preceded by ! to
* indicate negation). Returns -1 if negation matches, 1 if there is
* a positive match, 0 if there is no match at all.
*/
int
match_pattern_list(const char *string, const char *pattern, u_int len,
int dolower)
{
char sub[1024];
int negated;
int got_positive;
u_int i, subi;
got_positive = 0;
for (i = 0; i < len;) {
/* Check if the subpattern is negated. */
if (pattern[i] == '!') {
negated = 1;
i++;
} else
negated = 0;
/*
* Extract the subpattern up to a comma or end. Convert the
* subpattern to lowercase.
*/
for (subi = 0;
i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
subi++, i++)
sub[subi] = dolower && isupper((u_char)pattern[i]) ?
tolower((u_char)pattern[i]) : pattern[i];
/* If subpattern too long, return failure (no match). */
if (subi >= sizeof(sub) - 1)
return 0;
/* If the subpattern was terminated by a comma, skip the comma. */
if (i < len && pattern[i] == ',')
i++;
/* Null-terminate the subpattern. */
sub[subi] = '\0';
/* Try to match the subpattern against the string. */
if (match_pattern(string, sub)) {
if (negated)
return -1; /* Negative */
else
got_positive = 1; /* Positive */
}
}
/*
* Return success if got a positive match. If there was a negative
* match, we have already returned -1 and never get here.
*/
return got_positive;
}
/*
* Tries to match the host name (which must be in all lowercase) against the
* comma-separated sequence of subpatterns (each possibly preceded by ! to
* indicate negation). Returns -1 if negation matches, 1 if there is
* a positive match, 0 if there is no match at all.
*/
int
match_hostname(const char *host, const char *pattern, u_int len)
{
return match_pattern_list(host, pattern, len, 1);
}
/*
* returns 0 if we get a negative match for the hostname or the ip
* or if we get no match at all. returns -1 on error, or 1 on
* successful match.
*/
int
match_host_and_ip(const char *host, const char *ipaddr,
const char *patterns)
{
int mhost, mip;
/* error in ipaddr match */
if ((mip = addr_match_list(ipaddr, patterns)) == -2)
return -1;
else if (mip == -1) /* negative ip address match */
return 0;
/* negative hostname match */
if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1)
return 0;
/* no match at all */
if (mhost == 0 && mip == 0)
return 0;
return 1;
}
/*
* match user, user@host_or_ip, user@host_or_ip_list against pattern
*/
int
match_user(const char *user, const char *host, const char *ipaddr,
const char *pattern)
{
char *p, *pat;
int ret;
if ((p = strchr(pattern,'@')) == NULL)
return match_pattern(user, pattern);
pat = xstrdup(pattern);
p = strchr(pat, '@');
*p++ = '\0';
if ((ret = match_pattern(user, pat)) == 1)
ret = match_host_and_ip(host, ipaddr, p);
free(pat);
return ret;
}
/*
* Returns first item from client-list that is also supported by server-list,
* caller must free the returned string.
*/
#define MAX_PROP 40
#define SEP ","
char *
match_list(const char *client, const char *server, u_int *next)
{
char *sproposals[MAX_PROP];
char *c, *s, *p, *ret, *cp, *sp;
int i, j, nproposals;
c = cp = xstrdup(client);
s = sp = xstrdup(server);
for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
(p = strsep(&sp, SEP)), i++) {
if (i < MAX_PROP)
sproposals[i] = p;
else
break;
}
nproposals = i;
for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
(p = strsep(&cp, SEP)), i++) {
for (j = 0; j < nproposals; j++) {
if (strcmp(p, sproposals[j]) == 0) {
ret = xstrdup(p);
if (next != NULL)
*next = (cp == NULL) ?
strlen(c) : (u_int)(cp - c);
free(c);
free(s);
return ret;
}
}
}
if (next != NULL)
*next = strlen(c);
free(c);
free(s);
return NULL;
}

@ -0,0 +1,27 @@
/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 MATCH_H
#define MATCH_H
int match_pattern(const char *, const char *);
int match_pattern_list(const char *, const char *, u_int, int);
int match_hostname(const char *, const char *, u_int);
int match_host_and_ip(const char *, const char *, const char *);
int match_user(const char *, const char *, const char *, const char *);
char *match_list(const char *, const char *, u_int *);
/* addrmatch.c */
int addr_match_list(const char *, const char *);
int addr_match_cidr_list(const char *, const char *);
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,532 @@
/* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* 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.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* 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.
*/
/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */
#include "includes.h"
#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
/*
* Some defines to make it easier to keep the code in sync with upstream.
* getopt opterr optind optopt optreset optarg are all in defines.h which is
* pulled in by includes.h.
*/
#define warnx logit
#if 0
#include <err.h>
#include <getopt.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "log.h"
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, match;
current_argv = place;
match = -1;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
if (posixly_correct == -1 || optreset)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
if (*options == '+' || *options == '-')
options++;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#if 0
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}
#endif
#endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */

@ -0,0 +1,287 @@
/* $Id: openbsd-compat.h,v 1.62 2014/09/30 23:43:08 djm Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
* Copyright (c) 2003 Ben Lindstrom. All rights reserved.
* Copyright (c) 2002 Tim Rice. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _OPENBSD_COMPAT_H
#define _OPENBSD_COMPAT_H
#include "includes.h"
#include <sys/types.h>
#include <pwd.h>
#include <sys/socket.h>
/* OpenBSD function replacements */
#include "base64.h"
#include "sigact.h"
#include "glob.h"
#include "readpassphrase.h"
#include "vis.h"
#include "getrrsetbyname.h"
#include "sha2.h"
#include "blf.h"
#ifndef HAVE_BASENAME
char *basename(const char *path);
#endif
#ifndef HAVE_BINDRESVPORT_SA
int bindresvport_sa(int sd, struct sockaddr *sa);
#endif
#ifndef HAVE_CLOSEFROM
void closefrom(int);
#endif
#ifndef HAVE_GETCWD
char *getcwd(char *pt, size_t size);
#endif
#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
char *realpath(const char *path, char *resolved);
#endif
#ifndef HAVE_RRESVPORT_AF
int rresvport_af(int *alport, sa_family_t af);
#endif
#ifndef HAVE_STRLCPY
/* #include <sys/types.h> XXX Still needed? */
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRLCAT
/* #include <sys/types.h> XXX Still needed? */
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_SETENV
int setenv(register const char *name, register const char *value, int rewrite);
#endif
#ifndef HAVE_STRMODE
void strmode(int mode, char *p);
#endif
#ifndef HAVE_STRPTIME
#include <time.h>
char *strptime(const char *buf, const char *fmt, struct tm *tm);
#endif
#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP)
int mkstemps(char *path, int slen);
int mkstemp(char *path);
char *mkdtemp(char *path);
#endif
#ifndef HAVE_DAEMON
int daemon(int nochdir, int noclose);
#endif
#ifndef HAVE_DIRNAME
char *dirname(const char *path);
#endif
#ifndef HAVE_FMT_SCALED
#define FMT_SCALED_STRSIZE 7
int fmt_scaled(long long number, char *result);
#endif
#ifndef HAVE_SCAN_SCALED
int scan_scaled(char *, long long *);
#endif
#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
char *inet_ntoa(struct in_addr in);
#endif
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifndef HAVE_STRSEP
char *strsep(char **stringp, const char *delim);
#endif
#ifndef HAVE_SETPROCTITLE
void setproctitle(const char *fmt, ...);
void compat_init_setproctitle(int argc, char *argv[]);
#endif
#ifndef HAVE_GETGROUPLIST
/* #include <grp.h> XXXX Still needed ? */
int getgrouplist(const char *, gid_t, gid_t *, int *);
#endif
#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
int BSDgetopt(int argc, char * const *argv, const char *opts);
#include "openbsd-compat/getopt.h"
#endif
#if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0
# include <sys/types.h>
# include <sys/uio.h>
int writev(int, struct iovec *, int);
#endif
/* Home grown routines */
#include "bsd-misc.h"
#include "bsd-setres_id.h"
#include "bsd-statvfs.h"
#include "bsd-waitpid.h"
#include "bsd-poll.h"
#ifndef HAVE_GETPEEREID
int getpeereid(int , uid_t *, gid_t *);
#endif
#ifdef HAVE_ARC4RANDOM
# ifndef HAVE_ARC4RANDOM_STIR
# define arc4random_stir()
# endif
#else
unsigned int arc4random(void);
void arc4random_stir(void);
#endif /* !HAVE_ARC4RANDOM */
#ifndef HAVE_ARC4RANDOM_BUF
void arc4random_buf(void *, size_t);
#endif
#ifndef HAVE_ARC4RANDOM_UNIFORM
u_int32_t arc4random_uniform(u_int32_t);
#endif
#ifndef HAVE_ASPRINTF
int asprintf(char **, const char *, ...);
#endif
#ifndef HAVE_OPENPTY
# include <sys/ioctl.h> /* for struct winsize */
int openpty(int *, int *, char *, struct termios *, struct winsize *);
#endif /* HAVE_OPENPTY */
/* #include <sys/types.h> XXX needed? For size_t */
#ifndef HAVE_SNPRINTF
int snprintf(char *, size_t, SNPRINTF_CONST char *, ...);
#endif
#ifndef HAVE_STRTOLL
long long strtoll(const char *, char **, int);
#endif
#ifndef HAVE_STRTOUL
unsigned long strtoul(const char *, char **, int);
#endif
#ifndef HAVE_STRTOULL
unsigned long long strtoull(const char *, char **, int);
#endif
#ifndef HAVE_STRTONUM
long long strtonum(const char *, long long, long long, const char **);
#endif
/* multibyte character support */
#ifndef HAVE_MBLEN
# define mblen(x, y) 1
#endif
#if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF)
# include <stdarg.h>
#endif
#ifndef HAVE_VASPRINTF
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_VSNPRINTF
int vsnprintf(char *, size_t, const char *, va_list);
#endif
#ifndef HAVE_USER_FROM_UID
char *user_from_uid(uid_t, int);
#endif
#ifndef HAVE_GROUP_FROM_GID
char *group_from_gid(gid_t, int);
#endif
#ifndef HAVE_TIMINGSAFE_BCMP
int timingsafe_bcmp(const void *, const void *, size_t);
#endif
#ifndef HAVE_BCRYPT_PBKDF
int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
u_int8_t *, size_t, unsigned int);
#endif
#ifndef HAVE_EXPLICIT_BZERO
void explicit_bzero(void *p, size_t n);
#endif
void *xmmap(size_t size);
char *xcrypt(const char *password, const char *salt);
char *shadow_pw(struct passwd *pw);
/* rfc2553 socket API replacements */
#include "fake-rfc2553.h"
/* Routines for a single OS platform */
#include "bsd-cray.h"
#include "bsd-cygwin_util.h"
#include "port-aix.h"
#include "port-irix.h"
#include "port-linux.h"
#include "port-solaris.h"
#include "port-tun.h"
#include "port-uw.h"
/* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */
#if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE)
# include <features.h>
# if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ)
# if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0)
# include <sys/socket.h> /* Ensure include guard is defined */
# undef FD_SET
# undef FD_ISSET
# define FD_SET(n, set) kludge_FD_SET(n, set)
# define FD_ISSET(n, set) kludge_FD_ISSET(n, set)
void kludge_FD_SET(int, fd_set *);
int kludge_FD_ISSET(int, fd_set *);
# endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */
# endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */
#endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */
#endif /* _OPENBSD_COMPAT_H */

@ -0,0 +1,114 @@
/* $OpenBSD: pwcache.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */
/*
* Copyright (c) 1989, 1993
* 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/gen/pwcache.c */
#include "includes.h"
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCACHE 64 /* power of 2 */
#define MASK (NCACHE - 1) /* bits to store with */
#ifndef HAVE_USER_FROM_UID
char *
user_from_uid(uid_t uid, int nouser)
{
static struct ncache {
uid_t uid;
char *name;
} c_uid[NCACHE];
static int pwopen;
static char nbuf[15]; /* 32 bits == 10 digits */
struct passwd *pw;
struct ncache *cp;
cp = c_uid + (uid & MASK);
if (cp->uid != uid || cp->name == NULL) {
if (pwopen == 0) {
#ifdef HAVE_SETPASSENT
setpassent(1);
#endif
pwopen = 1;
}
if ((pw = getpwuid(uid)) == NULL) {
if (nouser)
return (NULL);
(void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
}
cp->uid = uid;
if (cp->name != NULL)
free(cp->name);
cp->name = strdup(pw ? pw->pw_name : nbuf);
}
return (cp->name);
}
#endif
#ifndef HAVE_GROUP_FROM_GID
char *
group_from_gid(gid_t gid, int nogroup)
{
static struct ncache {
gid_t gid;
char *name;
} c_gid[NCACHE];
static int gropen;
static char nbuf[15]; /* 32 bits == 10 digits */
struct group *gr;
struct ncache *cp;
cp = c_gid + (gid & MASK);
if (cp->gid != gid || cp->name == NULL) {
if (gropen == 0) {
#ifdef HAVE_SETGROUPENT
setgroupent(1);
#endif
gropen = 1;
}
if ((gr = getgrgid(gid)) == NULL) {
if (nogroup)
return (NULL);
(void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
}
cp->gid = gid;
if (cp->name != NULL)
free(cp->name);
cp->name = strdup(gr ? gr->gr_name : nbuf);
}
return (cp->name);
}
#endif

@ -0,0 +1,406 @@
/* $OpenBSD: sshbuf.c,v 1.2 2014/06/25 14:16:09 deraadt 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 <sys/types.h>
#include <sys/param.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ssherr.h"
#include "sshbuf.h"
static inline int
sshbuf_check_sanity(const struct sshbuf *buf)
{
SSHBUF_TELL("sanity");
if (__predict_false(buf == NULL ||
(!buf->readonly && buf->d != buf->cd) ||
buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX ||
buf->cd == NULL ||
(buf->dont_free && (buf->readonly || buf->parent != NULL)) ||
buf->max_size > SSHBUF_SIZE_MAX ||
buf->alloc > buf->max_size ||
buf->size > buf->alloc ||
buf->off > buf->size)) {
/* Do not try to recover from corrupted buffer internals */
SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
return SSH_ERR_INTERNAL_ERROR;
}
return 0;
}
static void
sshbuf_maybe_pack(struct sshbuf *buf, int force)
{
SSHBUF_DBG(("force %d", force));
SSHBUF_TELL("pre-pack");
if (buf->off == 0 || buf->readonly || buf->refcount > 1)
return;
if (force ||
(buf->off >= SSHBUF_PACK_MIN && buf->off >= buf->size / 2)) {
memmove(buf->d, buf->d + buf->off, buf->size - buf->off);
buf->size -= buf->off;
buf->off = 0;
SSHBUF_TELL("packed");
}
}
struct sshbuf *
sshbuf_new(void)
{
struct sshbuf *ret;
if ((ret = calloc(sizeof(*ret), 1)) == NULL)
return NULL;
ret->alloc = SSHBUF_SIZE_INIT;
ret->max_size = SSHBUF_SIZE_MAX;
ret->readonly = 0;
ret->refcount = 1;
ret->parent = NULL;
if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) {
free(ret);
return NULL;
}
return ret;
}
struct sshbuf *
sshbuf_from(const void *blob, size_t len)
{
struct sshbuf *ret;
if (blob == NULL || len > SSHBUF_SIZE_MAX ||
(ret = calloc(sizeof(*ret), 1)) == NULL)
return NULL;
ret->alloc = ret->size = ret->max_size = len;
ret->readonly = 1;
ret->refcount = 1;
ret->parent = NULL;
ret->cd = blob;
ret->d = NULL;
return ret;
}
int
sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent)
{
int r;
if ((r = sshbuf_check_sanity(child)) != 0 ||
(r = sshbuf_check_sanity(parent)) != 0)
return r;
child->parent = parent;
child->parent->refcount++;
return 0;
}
struct sshbuf *
sshbuf_fromb(struct sshbuf *buf)
{
struct sshbuf *ret;
if (sshbuf_check_sanity(buf) != 0)
return NULL;
if ((ret = sshbuf_from(sshbuf_ptr(buf), sshbuf_len(buf))) == NULL)
return NULL;
if (sshbuf_set_parent(ret, buf) != 0) {
sshbuf_free(ret);
return NULL;
}
return ret;
}
void
sshbuf_init(struct sshbuf *ret)
{
bzero(ret, sizeof(*ret));
ret->alloc = SSHBUF_SIZE_INIT;
ret->max_size = SSHBUF_SIZE_MAX;
ret->readonly = 0;
ret->dont_free = 1;
ret->refcount = 1;
if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL)
ret->alloc = 0;
}
void
sshbuf_free(struct sshbuf *buf)
{
int dont_free = 0;
if (buf == NULL)
return;
/*
* The following will leak on insane buffers, but this is the safest
* course of action - an invalid pointer or already-freed pointer may
* have been passed to us and continuing to scribble over memory would
* be bad.
*/
if (sshbuf_check_sanity(buf) != 0)
return;
/*
* If we are a child, the free our parent to decrement its reference
* count and possibly free it.
*/
if (buf->parent != NULL) {
sshbuf_free(buf->parent);
buf->parent = NULL;
}
/*
* If we are a parent with still-extant children, then don't free just
* yet. The last child's call to sshbuf_free should decrement our
* refcount to 0 and trigger the actual free.
*/
buf->refcount--;
if (buf->refcount > 0)
return;
dont_free = buf->dont_free;
if (!buf->readonly) {
bzero(buf->d, buf->alloc);
free(buf->d);
}
bzero(buf, sizeof(*buf));
if (!dont_free)
free(buf);
}
void
sshbuf_reset(struct sshbuf *buf)
{
u_char *d;
if (buf->readonly || buf->refcount > 1) {
/* Nonsensical. Just make buffer appear empty */
buf->off = buf->size;
return;
}
if (sshbuf_check_sanity(buf) == 0)
bzero(buf->d, buf->alloc);
buf->off = buf->size = 0;
if (buf->alloc != SSHBUF_SIZE_INIT) {
if ((d = realloc(buf->d, SSHBUF_SIZE_INIT)) != NULL) {
buf->cd = buf->d = d;
buf->alloc = SSHBUF_SIZE_INIT;
}
}
}
size_t
sshbuf_max_size(const struct sshbuf *buf)
{
return buf->max_size;
}
size_t
sshbuf_alloc(const struct sshbuf *buf)
{
return buf->alloc;
}
const struct sshbuf *
sshbuf_parent(const struct sshbuf *buf)
{
return buf->parent;
}
u_int
sshbuf_refcount(const struct sshbuf *buf)
{
return buf->refcount;
}
int
sshbuf_set_max_size(struct sshbuf *buf, size_t max_size)
{
size_t rlen;
u_char *dp;
int r;
SSHBUF_DBG(("set max buf = %p len = %zu", buf, max_size));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (max_size == buf->max_size)
return 0;
if (buf->readonly || buf->refcount > 1)
return SSH_ERR_BUFFER_READ_ONLY;
if (max_size > SSHBUF_SIZE_MAX)
return SSH_ERR_NO_BUFFER_SPACE;
/* pack and realloc if necessary */
sshbuf_maybe_pack(buf, max_size < buf->size);
if (max_size < buf->alloc && max_size > buf->size) {
if (buf->size < SSHBUF_SIZE_INIT)
rlen = SSHBUF_SIZE_INIT;
else
rlen = roundup(buf->size, SSHBUF_SIZE_INC);
if (rlen > max_size)
rlen = max_size;
bzero(buf->d + buf->size, buf->alloc - buf->size);
SSHBUF_DBG(("new alloc = %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
buf->cd = buf->d = dp;
buf->alloc = rlen;
}
SSHBUF_TELL("new-max");
if (max_size < buf->alloc)
return SSH_ERR_NO_BUFFER_SPACE;
buf->max_size = max_size;
return 0;
}
size_t
sshbuf_len(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0)
return 0;
return buf->size - buf->off;
}
size_t
sshbuf_avail(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)
return 0;
return buf->max_size - (buf->size - buf->off);
}
const u_char *
sshbuf_ptr(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0)
return NULL;
return buf->cd + buf->off;
}
u_char *
sshbuf_mutable_ptr(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)
return NULL;
return buf->d + buf->off;
}
int
sshbuf_check_reserve(const struct sshbuf *buf, size_t len)
{
int r;
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (buf->readonly || buf->refcount > 1)
return SSH_ERR_BUFFER_READ_ONLY;
SSHBUF_TELL("check");
/* Check that len is reasonable and that max_size + available < len */
if (len > buf->max_size || buf->max_size - len < buf->size - buf->off)
return SSH_ERR_NO_BUFFER_SPACE;
return 0;
}
int
sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp)
{
size_t rlen, need;
u_char *dp;
int r;
if (dpp != NULL)
*dpp = NULL;
SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len));
if ((r = sshbuf_check_reserve(buf, len)) != 0)
return r;
/*
* If the requested allocation appended would push us past max_size
* then pack the buffer, zeroing buf->off.
*/
sshbuf_maybe_pack(buf, buf->size + len > buf->max_size);
SSHBUF_TELL("reserve");
if (len + buf->size > buf->alloc) {
/*
* Prefer to alloc in SSHBUF_SIZE_INC units, but
* allocate less if doing so would overflow max_size.
*/
need = len + buf->size - buf->alloc;
rlen = roundup(buf->alloc + need, SSHBUF_SIZE_INC);
SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen));
if (rlen > buf->max_size)
rlen = buf->alloc + need;
SSHBUF_DBG(("adjusted rlen %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL) {
SSHBUF_DBG(("realloc fail"));
if (dpp != NULL)
*dpp = NULL;
return SSH_ERR_ALLOC_FAIL;
}
buf->alloc = rlen;
buf->cd = buf->d = dp;
if ((r = sshbuf_check_reserve(buf, len)) < 0) {
/* shouldn't fail */
if (dpp != NULL)
*dpp = NULL;
return r;
}
}
dp = buf->d + buf->size;
buf->size += len;
SSHBUF_TELL("done");
if (dpp != NULL)
*dpp = dp;
return 0;
}
int
sshbuf_consume(struct sshbuf *buf, size_t len)
{
int r;
SSHBUF_DBG(("len = %zu", len));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (len == 0)
return 0;
if (len > sshbuf_len(buf))
return SSH_ERR_MESSAGE_INCOMPLETE;
buf->off += len;
SSHBUF_TELL("done");
return 0;
}
int
sshbuf_consume_end(struct sshbuf *buf, size_t len)
{
int r;
SSHBUF_DBG(("len = %zu", len));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (len == 0)
return 0;
if (len > sshbuf_len(buf))
return SSH_ERR_MESSAGE_INCOMPLETE;
buf->size -= len;
SSHBUF_TELL("done");
return 0;
}

@ -0,0 +1,336 @@
/* $OpenBSD: sshbuf.h,v 1.3 2014/06/24 01:13:21 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 _SSHBUF_H
#define _SSHBUF_H
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef WITH_OPENSSL
# include <openssl/bn.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */
#define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */
#define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */
#define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */
/*
* NB. do not depend on the internals of this. It will be made opaque
* one day.
*/
struct sshbuf {
u_char *d; /* Data */
const u_char *cd; /* Const data */
size_t off; /* First available byte is buf->d + buf->off */
size_t size; /* Last byte is buf->d + buf->size - 1 */
size_t max_size; /* Maximum size of buffer */
size_t alloc; /* Total bytes allocated to buf->d */
int readonly; /* Refers to external, const data */
int dont_free; /* Kludge to support sshbuf_init */
u_int refcount; /* Tracks self and number of child buffers */
struct sshbuf *parent; /* If child, pointer to parent */
};
#ifndef SSHBUF_NO_DEPREACTED
/*
* NB. Please do not use sshbuf_init() in new code. Please use sshbuf_new()
* instead. sshbuf_init() is deprectated and will go away soon (it is
* only included to allow compat with buffer_* in OpenSSH)
*/
void sshbuf_init(struct sshbuf *buf);
#endif
/*
* Create a new sshbuf buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_new(void);
/*
* Create a new, read-only sshbuf buffer from existing data.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_from(const void *blob, size_t len);
/*
* Create a new, read-only sshbuf buffer from the contents of an existing
* buffer. The contents of "buf" must not change in the lifetime of the
* resultant buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_fromb(struct sshbuf *buf);
/*
* Create a new, read-only sshbuf buffer from the contents of a string in
* an existing buffer (the string is consumed in the process).
* The contents of "buf" must not change in the lifetime of the resultant
* buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp);
/*
* Clear and free buf
*/
void sshbuf_free(struct sshbuf *buf);
/*
* Reset buf, clearing its contents. NB. max_size is preserved.
*/
void sshbuf_reset(struct sshbuf *buf);
/*
* Return the maximum size of buf
*/
size_t sshbuf_max_size(const struct sshbuf *buf);
/*
* Set the maximum size of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size);
/*
* Returns the length of data in buf
*/
size_t sshbuf_len(const struct sshbuf *buf);
/*
* Returns number of bytes left in buffer before hitting max_size.
*/
size_t sshbuf_avail(const struct sshbuf *buf);
/*
* Returns a read-only pointer to the start of the the data in buf
*/
const u_char *sshbuf_ptr(const struct sshbuf *buf);
/*
* Returns a mutable pointer to the start of the the data in buf, or
* NULL if the buffer is read-only.
*/
u_char *sshbuf_mutable_ptr(const struct sshbuf *buf);
/*
* Check whether a reservation of size len will succeed in buf
* Safer to use than direct comparisons again sshbuf_avail as it copes
* with unsigned overflows correctly.
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_check_reserve(const struct sshbuf *buf, size_t len);
/*
* Reserve len bytes in buf.
* Returns 0 on success and a pointer to the first reserved byte via the
* optional dpp parameter or a negative * SSH_ERR_* error code on failure.
*/
int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp);
/*
* Consume len bytes from the start of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_consume(struct sshbuf *buf, size_t len);
/*
* Consume len bytes from the end of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_consume_end(struct sshbuf *buf, size_t len);
/* Extract or deposit some bytes */
int sshbuf_get(struct sshbuf *buf, void *v, size_t len);
int sshbuf_put(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v);
/* Append using a printf(3) format */
int sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
int sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap);
/* Functions to extract or store big-endian words of various sizes */
int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp);
int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp);
int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp);
int sshbuf_get_u8(struct sshbuf *buf, u_char *valp);
int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val);
int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
int sshbuf_put_u8(struct sshbuf *buf, u_char val);
/*
* Functions to extract or store SSH wire encoded strings (u32 len || data)
* The "cstring" variants admit no \0 characters in the string contents.
* Caller must free *valp.
*/
int sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp);
int sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp);
int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v);
int sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_put_cstring(struct sshbuf *buf, const char *v);
int sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v);
/*
* "Direct" variant of sshbuf_get_string, returns pointer into the sshbuf to
* avoid an malloc+memcpy. The pointer is guaranteed to be valid until the
* next sshbuf-modifying function call. Caller does not free.
*/
int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
size_t *lenp);
/* Skip past a string */
#define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL)
/* Another variant: "peeks" into the buffer without modifying it */
int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
size_t *lenp);
/*
* Functions to extract or store SSH wire encoded bignums and elliptic
* curve points.
*/
int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len);
#ifdef WITH_OPENSSL
int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v);
int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v);
int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v);
int sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v);
# ifdef OPENSSL_HAS_ECC
int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
/* Dump the contents of the buffer in a human-readable format */
void sshbuf_dump(struct sshbuf *buf, FILE *f);
/* Dump specified memory in a human-readable format */
void sshbuf_dump_data(const void *s, size_t len, FILE *f);
/* Return the hexadecimal representation of the contents of the buffer */
char *sshbuf_dtob16(struct sshbuf *buf);
/* Encode the contents of the buffer as base64 */
char *sshbuf_dtob64(struct sshbuf *buf);
/* Decode base64 data and append it to the buffer */
int sshbuf_b64tod(struct sshbuf *buf, const char *b64);
/* Macros for decoding/encoding integers */
#define PEEK_U64(p) \
(((u_int64_t)(((u_char *)(p))[0]) << 56) | \
((u_int64_t)(((u_char *)(p))[1]) << 48) | \
((u_int64_t)(((u_char *)(p))[2]) << 40) | \
((u_int64_t)(((u_char *)(p))[3]) << 32) | \
((u_int64_t)(((u_char *)(p))[4]) << 24) | \
((u_int64_t)(((u_char *)(p))[5]) << 16) | \
((u_int64_t)(((u_char *)(p))[6]) << 8) | \
(u_int64_t)(((u_char *)(p))[7]))
#define PEEK_U32(p) \
(((u_int32_t)(((u_char *)(p))[0]) << 24) | \
((u_int32_t)(((u_char *)(p))[1]) << 16) | \
((u_int32_t)(((u_char *)(p))[2]) << 8) | \
(u_int32_t)(((u_char *)(p))[3]))
#define PEEK_U16(p) \
(((u_int16_t)(((u_char *)(p))[0]) << 8) | \
(u_int16_t)(((u_char *)(p))[1]))
#define POKE_U64(p, v) \
do { \
((u_char *)(p))[0] = (((u_int64_t)(v)) >> 56) & 0xff; \
((u_char *)(p))[1] = (((u_int64_t)(v)) >> 48) & 0xff; \
((u_char *)(p))[2] = (((u_int64_t)(v)) >> 40) & 0xff; \
((u_char *)(p))[3] = (((u_int64_t)(v)) >> 32) & 0xff; \
((u_char *)(p))[4] = (((u_int64_t)(v)) >> 24) & 0xff; \
((u_char *)(p))[5] = (((u_int64_t)(v)) >> 16) & 0xff; \
((u_char *)(p))[6] = (((u_int64_t)(v)) >> 8) & 0xff; \
((u_char *)(p))[7] = ((u_int64_t)(v)) & 0xff; \
} while (0)
#define POKE_U32(p, v) \
do { \
((u_char *)(p))[0] = (((u_int64_t)(v)) >> 24) & 0xff; \
((u_char *)(p))[1] = (((u_int64_t)(v)) >> 16) & 0xff; \
((u_char *)(p))[2] = (((u_int64_t)(v)) >> 8) & 0xff; \
((u_char *)(p))[3] = ((u_int64_t)(v)) & 0xff; \
} while (0)
#define POKE_U16(p, v) \
do { \
((u_char *)(p))[0] = (((u_int64_t)(v)) >> 8) & 0xff; \
((u_char *)(p))[1] = ((u_int64_t)(v)) & 0xff; \
} while (0)
/* Internal definitions follow. Exposed for regress tests */
#ifdef SSHBUF_INTERNAL
/*
* Return the allocation size of buf
*/
size_t sshbuf_alloc(const struct sshbuf *buf);
/*
* Increment the reference count of buf.
*/
int sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent);
/*
* Return the parent buffer of buf, or NULL if it has no parent.
*/
const struct sshbuf *sshbuf_parent(const struct sshbuf *buf);
/*
* Return the reference count of buf
*/
u_int sshbuf_refcount(const struct sshbuf *buf);
# define SSHBUF_SIZE_INIT 256 /* Initial allocation */
# define SSHBUF_SIZE_INC 256 /* Preferred increment length */
# define SSHBUF_PACK_MIN 8192 /* Minimim packable offset */
/* # define SSHBUF_ABORT abort */
/* # define SSHBUF_DEBUG */
# ifndef SSHBUF_ABORT
# define SSHBUF_ABORT()
# endif
# ifdef SSHBUF_DEBUG
# define SSHBUF_TELL(what) do { \
printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
__FILE__, __LINE__, __func__, what, \
buf->size, buf->alloc, buf->off, buf->max_size); \
fflush(stdout); \
} while (0)
# define SSHBUF_DBG(x) do { \
printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
printf x; \
printf("\n"); \
fflush(stdout); \
} while (0)
# else
# define SSHBUF_TELL(what)
# define SSHBUF_DBG(x)
# endif
#endif /* SSHBUF_INTERNAL */
#endif /* _SSHBUF_H */

@ -0,0 +1,131 @@
/* $OpenBSD: ssherr.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.
*/
#include <errno.h>
#include <string.h>
#include "ssherr.h"
const char *
ssh_err(int n)
{
switch (n) {
case SSH_ERR_SUCCESS:
return "success";
case SSH_ERR_INTERNAL_ERROR:
return "unexpected internal error";
case SSH_ERR_ALLOC_FAIL:
return "memory allocation failed";
case SSH_ERR_MESSAGE_INCOMPLETE:
return "incomplete message";
case SSH_ERR_INVALID_FORMAT:
return "invalid format";
case SSH_ERR_BIGNUM_IS_NEGATIVE:
return "bignum is negative";
case SSH_ERR_STRING_TOO_LARGE:
return "string is too large";
case SSH_ERR_BIGNUM_TOO_LARGE:
return "bignum is too large";
case SSH_ERR_ECPOINT_TOO_LARGE:
return "elliptic curve point is too large";
case SSH_ERR_NO_BUFFER_SPACE:
return "insufficient buffer space";
case SSH_ERR_INVALID_ARGUMENT:
return "invalid argument";
case SSH_ERR_KEY_BITS_MISMATCH:
return "key bits do not match";
case SSH_ERR_EC_CURVE_INVALID:
return "invalid elliptic curve";
case SSH_ERR_KEY_TYPE_MISMATCH:
return "key type does not match";
case SSH_ERR_KEY_TYPE_UNKNOWN:
return "unknown or unsupported key type";
case SSH_ERR_EC_CURVE_MISMATCH:
return "elliptic curve does not match";
case SSH_ERR_EXPECTED_CERT:
return "plain key provided where certificate required";
case SSH_ERR_KEY_LACKS_CERTBLOB:
return "key lacks certificate data";
case SSH_ERR_KEY_CERT_UNKNOWN_TYPE:
return "unknown/unsupported certificate type";
case SSH_ERR_KEY_CERT_INVALID_SIGN_KEY:
return "invalid certificate signing key";
case SSH_ERR_KEY_INVALID_EC_VALUE:
return "invalid elliptic curve value";
case SSH_ERR_SIGNATURE_INVALID:
return "incorrect signature";
case SSH_ERR_LIBCRYPTO_ERROR:
return "error in libcrypto"; /* XXX fetch and return */
case SSH_ERR_UNEXPECTED_TRAILING_DATA:
return "unexpected bytes remain after decoding";
case SSH_ERR_SYSTEM_ERROR:
return strerror(errno);
case SSH_ERR_KEY_CERT_INVALID:
return "invalid certificate";
case SSH_ERR_AGENT_COMMUNICATION:
return "communication with agent failed";
case SSH_ERR_AGENT_FAILURE:
return "agent refused operation";
case SSH_ERR_DH_GEX_OUT_OF_RANGE:
return "DH GEX group out of range";
case SSH_ERR_DISCONNECTED:
return "disconnected";
case SSH_ERR_MAC_INVALID:
return "message authentication code incorrect";
case SSH_ERR_NO_CIPHER_ALG_MATCH:
return "no matching cipher found";
case SSH_ERR_NO_MAC_ALG_MATCH:
return "no matching MAC found";
case SSH_ERR_NO_COMPRESS_ALG_MATCH:
return "no matching compression method found";
case SSH_ERR_NO_KEX_ALG_MATCH:
return "no matching key exchange method found";
case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
return "no matching host key type found";
case SSH_ERR_PROTOCOL_MISMATCH:
return "protocol version mismatch";
case SSH_ERR_NO_PROTOCOL_VERSION:
return "could not read protocol version";
case SSH_ERR_NO_HOSTKEY_LOADED:
return "could not load host key";
case SSH_ERR_NEED_REKEY:
return "rekeying not supported by peer";
case SSH_ERR_PASSPHRASE_TOO_SHORT:
return "passphrase is too short (minimum four characters)";
case SSH_ERR_FILE_CHANGED:
return "file changed while reading";
case SSH_ERR_KEY_UNKNOWN_CIPHER:
return "key encrypted using unsupported cipher";
case SSH_ERR_KEY_WRONG_PASSPHRASE:
return "incorrect passphrase supplied to decrypt private key";
case SSH_ERR_KEY_BAD_PERMISSIONS:
return "bad permissions";
case SSH_ERR_KEY_CERT_MISMATCH:
return "certificate does not match key";
case SSH_ERR_KEY_NOT_FOUND:
return "key not found";
case SSH_ERR_AGENT_NOT_PRESENT:
return "agent not present";
case SSH_ERR_AGENT_NO_IDENTITIES:
return "agent contains no identities";
case SSH_ERR_KRL_BAD_MAGIC:
return "KRL file has invalid magic number";
case SSH_ERR_KEY_REVOKED:
return "Key is revoked";
default:
return "unknown error";
}
}

@ -0,0 +1,102 @@
/* $OpenBSD: xmalloc.c,v 1.29 2014/01/04 17:50:55 tedu Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* 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".
*/
#include "includes.h"
#include <sys/param.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "log.h"
void *
xmalloc(size_t size)
{
void *ptr;
if (size == 0)
fatal("xmalloc: zero size");
ptr = malloc(size);
if (ptr == NULL)
fatal("xmalloc: out of memory (allocating %zu bytes)", size);
return ptr;
}
void *
xcalloc(size_t nmemb, size_t size)
{
void *ptr;
if (size == 0 || nmemb == 0)
fatal("xcalloc: zero size");
if (SIZE_T_MAX / nmemb < size)
fatal("xcalloc: nmemb * size > SIZE_T_MAX");
ptr = calloc(nmemb, size);
if (ptr == NULL)
fatal("xcalloc: out of memory (allocating %zu bytes)",
size * nmemb);
return ptr;
}
void *
xrealloc(void *ptr, size_t nmemb, size_t size)
{
void *new_ptr;
size_t new_size = nmemb * size;
if (new_size == 0)
fatal("xrealloc: zero size");
if (SIZE_T_MAX / nmemb < size)
fatal("xrealloc: nmemb * size > SIZE_T_MAX");
if (ptr == NULL)
new_ptr = malloc(new_size);
else
new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL)
fatal("xrealloc: out of memory (new_size %zu bytes)",
new_size);
return new_ptr;
}
char *
xstrdup(const char *str)
{
size_t len;
char *cp;
len = strlen(str) + 1;
cp = xmalloc(len);
strlcpy(cp, str, len);
return cp;
}
int
xasprintf(char **ret, const char *fmt, ...)
{
va_list ap;
int i;
va_start(ap, fmt);
i = vasprintf(ret, fmt, ap);
va_end(ap);
if (i < 0 || *ret == NULL)
fatal("xasprintf: could not allocate memory");
return (i);
}
Loading…
Cancel
Save