mirror of http://galexander.org/git/simplesshd.git
the ones that I had to modify to get sftp-server to buildsigsegv_dump
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…
Reference in new issue