summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/misc.c')
-rw-r--r--crypto/openssh/misc.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index e4c8c32..ddd2b2d 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.92 2013/10/14 23:28:23 djm Exp $ */
+/* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -29,8 +29,9 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <sys/param.h>
+#include <sys/un.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -471,7 +472,7 @@ addargs(arglist *args, char *fmt, ...)
} else if (args->num+2 >= nalloc)
nalloc *= 2;
- args->list = xrealloc(args->list, nalloc, sizeof(char *));
+ args->list = xreallocarray(args->list, nalloc, sizeof(char *));
args->nalloc = nalloc;
args->list[args->num++] = cp;
args->list[args->num] = NULL;
@@ -550,7 +551,7 @@ tilde_expand_filename(const char *filename, uid_t uid)
if (path != NULL)
filename = path + 1;
- if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= MAXPATHLEN)
+ if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
fatal("tilde_expand_filename: Path too long");
return (ret);
@@ -788,6 +789,20 @@ get_u32(const void *vp)
return (v);
}
+u_int32_t
+get_u32_le(const void *vp)
+{
+ const u_char *p = (const u_char *)vp;
+ u_int32_t v;
+
+ v = (u_int32_t)p[0];
+ v |= (u_int32_t)p[1] << 8;
+ v |= (u_int32_t)p[2] << 16;
+ v |= (u_int32_t)p[3] << 24;
+
+ return (v);
+}
+
u_int16_t
get_u16(const void *vp)
{
@@ -826,6 +841,16 @@ put_u32(void *vp, u_int32_t v)
p[3] = (u_char)v & 0xff;
}
+void
+put_u32_le(void *vp, u_int32_t v)
+{
+ u_char *p = (u_char *)vp;
+
+ p[0] = (u_char)v & 0xff;
+ p[1] = (u_char)(v >> 8) & 0xff;
+ p[2] = (u_char)(v >> 16) & 0xff;
+ p[3] = (u_char)(v >> 24) & 0xff;
+}
void
put_u16(void *vp, u_int16_t v)
@@ -858,17 +883,24 @@ ms_to_timeval(struct timeval *tv, int ms)
time_t
monotime(void)
{
-#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+#if defined(HAVE_CLOCK_GETTIME) && \
+ (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))
struct timespec ts;
static int gettime_failed = 0;
if (!gettime_failed) {
+#if defined(CLOCK_BOOTTIME)
+ if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)
+ return (ts.tv_sec);
+#endif
+#if defined(CLOCK_MONOTONIC)
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
return (ts.tv_sec);
+#endif
debug3("clock_gettime: %s", strerror(errno));
gettime_failed = 1;
}
-#endif
+#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */
return time(NULL);
}
@@ -1025,6 +1057,53 @@ lowercase(char *s)
for (; *s; s++)
*s = tolower((u_char)*s);
}
+
+int
+unix_listener(const char *path, int backlog, int unlink_first)
+{
+ struct sockaddr_un sunaddr;
+ int saved_errno, sock;
+
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_UNIX;
+ if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
+ error("%s: \"%s\" too long for Unix domain socket", __func__,
+ path);
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ saved_errno = errno;
+ error("socket: %.100s", strerror(errno));
+ errno = saved_errno;
+ return -1;
+ }
+ if (unlink_first == 1) {
+ if (unlink(path) != 0 && errno != ENOENT)
+ error("unlink(%s): %.100s", path, strerror(errno));
+ }
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
+ saved_errno = errno;
+ error("bind: %.100s", strerror(errno));
+ close(sock);
+ error("%s: cannot bind to path: %s", __func__, path);
+ errno = saved_errno;
+ return -1;
+ }
+ if (listen(sock, backlog) < 0) {
+ saved_errno = errno;
+ error("listen: %.100s", strerror(errno));
+ close(sock);
+ unlink(path);
+ error("%s: cannot listen on path: %s", __func__, path);
+ errno = saved_errno;
+ return -1;
+ }
+ return sock;
+}
+
void
sock_set_v6only(int s)
{
OpenPOWER on IntegriCloud