From: Martin Willi Date: Wed, 26 Jun 2013 15:16:33 +0000 (+0200) Subject: stream: add support for UNIX stream services X-Git-Tag: 5.1.0rc1~10^2~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f04746d9b43311f5b62f98b987d3f0dcb406daa1;p=thirdparty%2Fstrongswan.git stream: add support for UNIX stream services --- diff --git a/src/libstrongswan/networking/streams/stream_manager.c b/src/libstrongswan/networking/streams/stream_manager.c index 38aaf9af9a..dbd221e2ad 100644 --- a/src/libstrongswan/networking/streams/stream_manager.c +++ b/src/libstrongswan/networking/streams/stream_manager.c @@ -248,6 +248,7 @@ METHOD(stream_manager_t, destroy, void, private_stream_manager_t *this) { remove_stream(this, stream_create_unix); + remove_service(this, stream_service_create_unix); this->streams->destroy(this->streams); this->services->destroy(this->services); @@ -281,6 +282,7 @@ stream_manager_t *stream_manager_create() ); add_stream(this, "unix://", stream_create_unix); + add_service(this, "unix://", stream_service_create_unix); return &this->public; } diff --git a/src/libstrongswan/networking/streams/stream_service.c b/src/libstrongswan/networking/streams/stream_service.c index 489edaef42..609ff3cac2 100644 --- a/src/libstrongswan/networking/streams/stream_service.c +++ b/src/libstrongswan/networking/streams/stream_service.c @@ -17,7 +17,11 @@ #include #include +#include #include +#include +#include +#include typedef struct private_stream_service_t private_stream_service_t; @@ -154,3 +158,50 @@ stream_service_t *stream_service_create_from_fd(int fd) return &this->public; } + +/** + * See header + */ +stream_service_t *stream_service_create_unix(char *uri) +{ + struct sockaddr_un addr; + mode_t old; + int fd, len; + + len = stream_parse_uri_unix(uri, &addr); + if (len == -1) + { + DBG1(DBG_NET, "invalid stream URI: '%s'", uri); + return NULL; + } + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + { + DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno)); + return NULL; + } + unlink(addr.sun_path); + + old = umask(~(S_IRWXU | S_IRWXG)); + if (bind(fd, (struct sockaddr*)&addr, len) < 0) + { + DBG1(DBG_NET, "binding socket '%s' failed: %s", uri, strerror(errno)); + close(fd); + return NULL; + } + umask(old); + if (chown(addr.sun_path, lib->caps->get_uid(lib->caps), + lib->caps->get_gid(lib->caps)) != 0) + { + DBG1(DBG_NET, "changing socket permissions for '%s' failed: %s", + uri, strerror(errno)); + } + if (listen(fd, 5) < 0) + { + DBG1(DBG_NET, "listen on socket '%s' failed: %s", uri, strerror(errno)); + unlink(addr.sun_path); + close(fd); + return NULL; + } + return stream_service_create_from_fd(fd); +} diff --git a/src/libstrongswan/networking/streams/stream_service.h b/src/libstrongswan/networking/streams/stream_service.h index f5da92ee7b..f864a7aeb7 100644 --- a/src/libstrongswan/networking/streams/stream_service.h +++ b/src/libstrongswan/networking/streams/stream_service.h @@ -75,4 +75,12 @@ struct stream_service_t { */ stream_service_t *stream_service_create_from_fd(int fd); +/** + * Create a service instance for UNIX sockets. + * + * @param uri UNIX socket specific URI, must start with "unix://" + * @return stream_service instance, NULL on failure + */ +stream_service_t *stream_service_create_unix(char *uri); + #endif /** STREAM_SERVICE_H_ @}*/