summaryrefslogtreecommitdiffstats
path: root/misc.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2014-07-18 14:11:24 +1000
committerDamien Miller <djm@mindrot.org>2014-07-18 14:11:24 +1000
commit7acefbbcbeab725420ea07397ae35992f505f702 (patch)
treebfb07917715d425438dab987a47ccd7a8d7f118b /misc.c
parent6262d760e00714523633bd989d62e273a3dca99a (diff)
- millert@cvs.openbsd.org 2014/07/15 15:54:14
[PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] [sshd_config.5 sshlogin.c] Add support for Unix domain socket forwarding. A remote TCP port may be forwarded to a local Unix domain socket and vice versa or both ends may be a Unix domain socket. This is a reimplementation of the streamlocal patches by William Ahern from: http://www.25thandclement.com/~william/projects/streamlocal.html OK djm@ markus@
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index 099c4ef8..739916ba 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.93 2014/04/20 02:30:25 djm Exp $ */
+/* $OpenBSD: misc.c,v 1.94 2014/07/15 15:54:14 millert Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <sys/param.h>
#include <stdarg.h>
@@ -1056,6 +1057,52 @@ 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)
{