diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-04-09 09:43:49 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-04-09 09:43:52 +0200 |
commit | c991b5223140e4ef311afac0f25272e602238826 (patch) | |
tree | 4bdc7c2f1972a1ab902d6ae5d5a70bb297cbb1f6 | |
parent | 5380a18c4dd488dc96eb68631d55592e4eac3cb5 (diff) | |
download | gnutls-c991b5223140e4ef311afac0f25272e602238826.tar.gz |
crywrap: was removed from gnutls tools
Its inclusion did not increase the attention paid to this
tool, not provided any significant advantage to gnutls' users
thus it was unbundled from the main library. The tool can be found at
https://github.com/nmav/crywrap
-rw-r--r-- | configure.ac | 52 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/crywrap/Makefile.am | 32 | ||||
-rw-r--r-- | src/crywrap/README | 2 | ||||
-rw-r--r-- | src/crywrap/crywrap.c | 1101 | ||||
-rw-r--r-- | src/crywrap/crywrap.h | 93 | ||||
-rw-r--r-- | src/crywrap/primes.h | 41 |
7 files changed, 0 insertions, 1325 deletions
diff --git a/configure.ac b/configure.ac index 36426db605..d9b7d06dab 100644 --- a/configure.ac +++ b/configure.ac @@ -826,52 +826,6 @@ AC_DEFINE([fread_file], [_gnutls_fread_file], [static lib rename]) AC_DEFINE([read_file], [_gnutls_read_file], [static lib rename]) AC_DEFINE([read_binary_file], [_gnutls_read_binary_file], [static lib rename]) -dnl Crywrap dependencies - AC_MSG_RESULT([*** -*** Checking dependencies for crywrap... -]) - -crywrap=no - -if test "$have_win" != "yes"; then - -AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/select.h sys/types.h sys/wait.h]) - -dnl ********************** -dnl * Typedefs & co -dnl ********************** -AC_CACHE_CHECK([return type of signal handlers],[ac_cv_type_signal],[AC_COMPILE_IFELSE( -[AC_LANG_PROGRAM([#include <sys/types.h> -#include <signal.h> -], - [return *(signal (0, 0)) (0) == 1;])], - [ac_cv_type_signal=int], - [ac_cv_type_signal=void])]) -AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type of signal handlers - (`int' or `void').]) - -AC_FUNC_SELECT_ARGTYPES -AC_CHECK_FUNCS([alarm atexit dup2 epoll_create kqueue memchr memset munmap \ - putenv regcomp scandir select socket strcasecmp strchr \ - strdup strerror strncasecmp strrchr strstr strtoul uname]) - -AC_ARG_ENABLE(crywrap, - AS_HELP_STRING([--disable-crywrap], [unconditionally disable the crywrap TLS proxy service])) - - - if test "x$enable_crywrap" != "xno" ; then - AC_CHECK_FUNCS([argp_usage],[ac_argp=yes],[ac_argp=no]) - if test "$ac_cv_func_daemon" != "no" && test "$ac_argp" != "no" && test "$with_libidn" != "no";then - crywrap=yes - fi - fi - -fi - -AM_CONDITIONAL(ENABLE_CRYWRAP, test "x$crywrap" != "xno") - -dnl end of crywrap requirements - dnl Some variables needed in makefiles YEAR=`date +%Y` AC_SUBST([YEAR], $YEAR) @@ -918,7 +872,6 @@ AC_CONFIG_FILES([ lib/x509/Makefile po/Makefile.in src/Makefile - src/crywrap/Makefile src/gl/Makefile tests/Makefile tests/windows/Makefile @@ -998,11 +951,6 @@ if features are disabled) FIPS140 mode: $enable_fips ]) -AC_MSG_NOTICE([Optional applications: - - crywrap app: $crywrap -]) - AC_MSG_NOTICE([Optional libraries: Guile wrappers: $opt_guile_bindings diff --git a/src/Makefile.am b/src/Makefile.am index fda8b9e05d..6ae280936c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,10 +27,6 @@ BUILT_SOURCES = srptool-args.c srptool-args.h \ danetool-args.c danetool-args.h p11tool-args.c p11tool-args.h \ tpmtool-args.c tpmtool-args.h systemkey-args.c systemkey-args.h -if ENABLE_CRYWRAP -SUBDIRS += crywrap -endif - EXTRA_DIST = args-std.def AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) diff --git a/src/crywrap/Makefile.am b/src/crywrap/Makefile.am deleted file mode 100644 index d86ca555d1..0000000000 --- a/src/crywrap/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Copyright (C) 2011-2012 Free Software Foundation, Inc. -# -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This file is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this file; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -AM_CFLAGS = $(WARN_CFLAGS) $(LIBIDN_CFLAGS) -AM_CPPFLAGS = \ - -I$(builddir)/../../lib/includes \ - -I$(srcdir)/../../lib/includes \ - -DSYSCONFDIR=\"${sysconfdir}\" \ - -DCRYWRAP_PATCHLEVEL=\"${CRYWRAP_PATCHLEVEL}\" - -# -I$(srcdir)/../../gl - -EXTRA_DIST = README -bin_PROGRAMS = crywrap - -crywrap_SOURCES = crywrap.c primes.h crywrap.h -crywrap_LDADD = ../../lib/libgnutls.la $(LIBIDN_LIBS) #../../gl/libgnu.la -crywrap_LDADD += $(LIB_CLOCK_GETTIME) diff --git a/src/crywrap/README b/src/crywrap/README deleted file mode 100644 index 9408304833..0000000000 --- a/src/crywrap/README +++ /dev/null @@ -1,2 +0,0 @@ -The crywrap program by Gergely Nagy is not part of the GnuTLS library, but is -distributed with GnuTLS. diff --git a/src/crywrap/crywrap.c b/src/crywrap/crywrap.c deleted file mode 100644 index 1277609be4..0000000000 --- a/src/crywrap/crywrap.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* -*- mode: c; c-file-style: "gnu" -*- - * crywrap.c -- CryWrap - * Copyright (C) 2003, 2004 Gergely Nagy <algernon@bonehunter.rulez.org> - * Copyright (C) 2011 Nikos Mavrogiannopoulos - * - * This file is part of CryWrap. - * - * CryWrap is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CryWrap is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** @file crywrap.c - * CryWrap itself. - */ - -#include <config.h> - -#include <argp.h> -#include <arpa/inet.h> -#include <errno.h> -#include <fcntl.h> -#include <gnutls/gnutls.h> -#include <gnutls/x509.h> -#include <grp.h> -#include <idna.h> -#include <netdb.h> -#include <netinet/in.h> -#include <pwd.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stringprep.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <syslog.h> -#include <stdarg.h> -#include <unistd.h> - -#include "crywrap.h" -#include "primes.h" - -static int system_log(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__ ((format(printf, 1, 2))) -#endif - ; - -static int system_log_error(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__ ((format(printf, 1, 2))) -#endif - ; - -static int debug_log(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__ ((format(printf, 1, 2))) -#endif - ; - -typedef int (*cry_log_func) (const char *format, ...) -#ifdef __GNUC__ - __attribute__ ((format(printf, 1, 2))) -#endif - ; - -static cry_log_func cry_log = system_log; -static cry_log_func cry_error = system_log_error; - -static void tls_audit_log_func(gnutls_session_t session, const char *str) -{ - char peer_name[NI_MAXHOST] = "Unknown"; - gnutls_transport_ptr_t r, s; - struct sockaddr_storage faddr; - socklen_t socklen = sizeof(struct sockaddr_storage); - - if (session != NULL) { - gnutls_transport_get_ptr2(session, &r, &s); - - /* Log the connection */ - if (getpeername - ((int) (long) r, (struct sockaddr *) &faddr, - &socklen) != 0) - cry_error("getpeername(): %s", strerror(errno)); - - cry_log("Peer %s: %s", peer_name, str); - } else - cry_log("%s", str); - -} - -/** @defgroup globals Global variables. - * @{ - */ - -/** An array of pids. - * This array holds the PIDs of all of our children, indexed by the - * socket the associated client connected to us. - */ -static pid_t main_pid = -1; /**< Pid of the main process */ -static const char *pidfile = _CRYWRAP_PIDFILE; /**< File to log our PID - into. */ - -/** GNUTLS server credentials. - */ -static gnutls_certificate_server_credentials cred; -static gnutls_dh_params dh_params; /**< GNUTLS DH parameters. */ -static gnutls_datum dh_file = { (void *) _crywrap_prime_dh_1024, sizeof(_crywrap_prime_dh_1024) }; - /**< Diffie Hellman parameters */ - -/** Bugreport address. - * Used by the argp suite. - */ -const char *argp_program_bug_address = "<bugs-gnutls@gnu.org>"; -/** Porgram version. - * Used by the argp suite. - */ -const char *argp_program_version = __CRYWRAP__ " " _CRYWRAP_VERSION; - -/* The certificate and key files */ -static char *pem_cert = NULL; -static char *pem_key = NULL; - - -/** The options CryWrap takes. - * Used by the argp suite. - */ -static const struct argp_option _crywrap_options[] = { - {NULL, 0, NULL, 0, "Mandatory options:", 1}, - {"destination", 'd', "IP/PORT", 0, "IP and port to connect to", 1}, - {"listen", 'l', "IP/PORT", 0, "IP and port to listen on", 1}, - {NULL, 0, NULL, 0, "TLS certificates:", 2}, - {"key", 'k', "FILE", 0, "Server key", 2}, - {"cert", 'c', "FILE", 0, "Server certificate", 2}, - {"ca", 'z', "FILE", 0, "CA certificate", 2}, - {"anon", 'a', NULL, 0, - "Enable anonymous authentication (no certificates)", 2}, - {"verify", 'v', "LEVEL", OPTION_ARG_OPTIONAL, - "Verify clients certificate (1: verify if exists, 2: require)", - 2}, - {NULL, 0, NULL, 0, "Other options:", 3}, - {"dhparams", 'r', "FILE", 0, - "Diffie Hellman (PKCS #3) parameters file", 3}, - {"user", 'u', "UID", 0, "User ID to run as", 3}, - {"pidfile", 'P', "PATH", 0, "File to log the PID into", 3}, - {"priority", 'p', "STRING", 0, - "GnuTLS ciphersuite priority string", 3}, - {"inetd", 'i', NULL, 0, "Enable inetd mode", 3}, - {"debug", 'D', NULL, 0, "Run the server into foreground", 3}, - {0, 0, 0, 0, NULL, 0} -}; - -static error_t _crywrap_config_parse_opt(int key, char *arg, - struct argp_state *state); -/** The main argp structure for Crywrap. - */ -static const struct argp _crywrap_argp = - { _crywrap_options, _crywrap_config_parse_opt, 0, - __CRYWRAP__ " -- Security for the masses\v" - "The --destination option is mandatory, as is --listen if --inetd " - "was not used.", - NULL, NULL, NULL -}; - -/** @} */ - -/** @defgroup signal Signal handlers & co. - * @{ - */ - -/** SIGCHLD handler - */ -static void _crywrap_sigchld_handler(int sig) -{ - pid_t child; - int status; - - while ((child = waitpid(-1, &status, WNOHANG)) > (pid_t) 0) - signal(sig, _crywrap_sigchld_handler); -} - -/* Helper functions to load a certificate and key - * files into memory. - */ -static gnutls_datum_t load_file(const char *file) -{ - gnutls_datum_t loaded_file = { NULL, 0 }; - - gnutls_load_file(file, &loaded_file); - - return loaded_file; -} - -/** Generic signal handler. - * This one removes the #pidfile, if necessary. - */ -static void _crywrap_sighandler(int sig) -{ - if (getpid() == main_pid) { - cry_log("Exiting on signal %d", sig); - if (pidfile && *pidfile) - unlink(pidfile); - closelog(); - exit(0); - } -} - -/** @} */ - -/** @defgroup parsing Option parsing - * @{ - */ - -/** Service resolver. - * Resolves a service - be it a name or a number. - * - * @param serv is the port to resolve. - * - * @returns The purt number, or -1 on error. - */ -static int _crywrap_port_get(const char *serv) -{ - int port; - struct servent *se; - - if (!serv) - return -1; - - se = getservbyname(serv, "tcp"); - if (!se) - port = atoi(serv); - else - port = ntohs(se->s_port); - - return port; -} - -/** Address resolver. - * Resolves an address - be it numeric or a hostname, IPv4 or IPv6. - * - * @param hostname is the host to resolve. - * @param addr is the structure to put the result into. - * - * @returns Zero on success, -1 on error. - */ -static int -_crywrap_addr_get(const char *hostname, struct sockaddr_storage **addr) -{ - struct addrinfo *res; - struct addrinfo hints; - ssize_t len; - char *lz = NULL; - - if (idna_to_ascii_lz(hostname, &lz, 0) != IDNA_SUCCESS) - return -1; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_IP; - *addr = calloc(1, sizeof(struct sockaddr_storage)); - if (*addr == NULL) { - free(lz); - return -1; - } - - if (getaddrinfo(lz, NULL, &hints, &res) != 0) { - free(lz); - return -1; - } - - free(lz); - - switch (res->ai_addr->sa_family) { - case AF_INET: - len = sizeof(struct sockaddr_in); - break; - case AF_INET6: - len = sizeof(struct sockaddr_in6); - break; - default: - freeaddrinfo(res); - return -1; - } - - if (len < (ssize_t) res->ai_addrlen) { - freeaddrinfo(res); - return -1; - } - - memcpy(*addr, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - - return 0; -} - -/** Parse a HOST/IP pair. - * Splits up a given HOST/IP pair, and converts them into structures - * directly usable by libc routines. - * - * @param ip is the HOST/IP pair to parse. - * @param port is a pointer to an integer where the port number should - * go. - * @param addr is the destination of the resolved and parsed IP. - * - * @returns Zero on success, -1 on error. - */ -static int -_crywrap_parse_ip(const char *ip, in_port_t * port, - struct sockaddr_storage **addr, char **host) -{ - char *s_ip = NULL; - char *tmp; - int ret; - - tmp = strchr(ip, '/'); - - if (!tmp) - return -1; - - if (tmp == ip) { - s_ip = strdup("0.0.0.0"); - *port = (in_port_t) _crywrap_port_get(&ip[1]); - } else { - *port = (in_port_t) _crywrap_port_get(&tmp[1]); - s_ip = strndup(ip, tmp - ip); - } - - if (!*port) - return -1; - - if (host) - *host = strdup(s_ip); - - ret = _crywrap_addr_get(s_ip, addr); - free(s_ip); - return ret; -} - -/** Argument parsing routine. - * Used by the argp suite. - */ -static error_t -_crywrap_config_parse_opt(int key, char *arg, struct argp_state *state) -{ - crywrap_config_t *cfg = (crywrap_config_t *) state->input; - int ret; - - switch (key) { - case 'D': - cfg->debug = 1; - cry_log = debug_log; - cry_error = debug_log; - break; - case 'd': - if (_crywrap_parse_ip - (arg, &cfg->dest.port, &cfg->dest.addr, - &cfg->dest.host) < 0) - argp_error(state, - "Could not resolve address: `%s'", arg); - break; - case 'l': - if (_crywrap_parse_ip(arg, &cfg->listen.port, - &cfg->listen.addr, NULL) < 0) - argp_error(state, - "Could not resolve address: `%s'", arg); - break; - case 'u': - cfg->uid = atoi(arg); - break; - case 'P': - if (arg && *arg) - cfg->pidfile = strdup(arg); - else - cfg->pidfile = NULL; - break; - case 'r': - if (arg && *arg) { - dh_file = load_file(arg); - if (dh_file.data == NULL) - argp_error(state, - "error loading Diffie Hellman parameters file: %s.", - arg); - } - break; - case 'p': - if (arg && *arg) { - const char *pos; - ret = - gnutls_priority_init(&cfg->priority, arg, - &pos); - if (ret < 0) - argp_error(state, - "error in priority string at: %s.", - pos); - } - break; - case 'c': - if (arg && *arg) - pem_cert = strdup(arg); - break; - case 'k': - if (arg && *arg) - pem_key = strdup(arg); - break; - - break; - case 'i': - cfg->inetd = 1; - break; - case 'a': - { - const char *pos; - ret = - gnutls_priority_init(&cfg->priority, - "NORMAL:+ANON-ECDH:+ANON-DH", - &pos); - if (ret < 0) - argp_error(state, - "error in priority string at: %s.", - pos); - } - cfg->verify = 0; - cfg->anon = 1; - break; - case 'v': - cfg->verify = (arg) ? atoi(arg) : 1; - break; - case 'z': - ret = gnutls_certificate_set_x509_trust_file(cred, arg, - GNUTLS_X509_FMT_PEM); - if (ret < 0) - argp_error(state, - "error reading X.509 CA file: %s.", - gnutls_strerror(ret)); - break; - - case ARGP_KEY_END: - if (!cfg->inetd) { - if (!cfg->listen.addr || !cfg->dest.addr) - argp_error - (state, - "a listening and a destination address must be set!"); - } else if (!cfg->dest.addr) - argp_error(state, - "a destination address must be set!"); - if (cfg->anon) - break; - if (pem_cert == NULL || pem_key == NULL) - ret = - gnutls_certificate_set_x509_key_file(cred, - _CRYWRAP_PEMFILE, - _CRYWRAP_PEMFILE, - GNUTLS_X509_FMT_PEM); - else - ret = - gnutls_certificate_set_x509_key_file(cred, - pem_cert, - pem_key, - GNUTLS_X509_FMT_PEM); - - if (ret < 0) - argp_error(state, - "Error reading X.509 key or certificate file: %s", - gnutls_strerror(ret)); - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -/** Configuration parsing. - * Sets up the default values, and parses the command-line options - * using argp. - * - * @note Does not return if an error occurred. - */ -static crywrap_config_t *_crywrap_config_parse(int argc, char **argv) -{ - crywrap_config_t *config = - (crywrap_config_t *) malloc(sizeof(crywrap_config_t)); - - if (config == NULL) - return NULL; - - config->listen.port = 0; - config->listen.addr = NULL; - config->dest.port = 0; - config->dest.addr = NULL; - config->priority = NULL; - config->uid = _CRYWRAP_UID; - config->pidfile = _CRYWRAP_PIDFILE; - config->inetd = 0; - config->anon = 0; - config->verify = 0; - - argp_parse(&_crywrap_argp, argc, argv, 0, 0, config); - - if (config->priority == NULL) - gnutls_priority_init(&config->priority, "NORMAL", NULL); - - return config; -} - -/** @} */ - -/** @defgroup tls Lower-level TLS routines. - * @{ - */ - -/** Create a GNUTLS session. - * Initialises the cyphers and the session database for a new TLS - * session. - * - * @returns The newly created TLS session. - */ -static gnutls_session_t -_crywrap_tls_session_create(const crywrap_config_t * config) -{ - gnutls_session_t session; - int ret; - - gnutls_init(&session, GNUTLS_SERVER); - - if (config->anon) { - gnutls_credentials_set(session, GNUTLS_CRD_ANON, cred); - } else { - gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, - cred); - } - - ret = gnutls_priority_set(session, config->priority); - if (ret < 0) { - cry_error("Error setting priority %s: ", - gnutls_strerror(ret)); - exit(4); - } - - if (config->verify == 1) - gnutls_certificate_server_set_request(session, - GNUTLS_CERT_REQUEST); - else if (config->verify == 2) - gnutls_certificate_server_set_request(session, - GNUTLS_CERT_REQUIRE); - - return session; -} - -/** Generate initial DH and RSA params. - * Loads the pre-generated DH primes. - */ -static void _crywrap_tls_init(void) -{ -#ifdef ENABLE_DHE - gnutls_dh_params_init(&dh_params); - gnutls_dh_params_import_pkcs3(dh_params, &dh_file, - GNUTLS_X509_FMT_PEM); - - gnutls_certificate_set_dh_params(cred, dh_params); -#endif -} - -/** @} */ - -/** @defgroup networking Networking - * @{ - */ - -/** Bind to an address. - * This one binds to an address, handles errors and anything that may - * arise. - * - * @param ai is the address information. - * @param listen_port is the port to bind to, and listen on. - * - * @returns The bound filedescriptor, or -1 on error. - */ -static int _crywrap_bind(const struct addrinfo *ai, int listen_port) -{ - int ret; - const int one = 1; - int listenfd; - char sock_name[NI_MAXHOST]; - - listenfd = socket(ai->ai_family, SOCK_STREAM, IPPROTO_IP); - if (listenfd == -1) { - cry_error("socket: %s", strerror(errno)); - return -1; - } - - memset(sock_name, 0, sizeof(sock_name)); - getnameinfo((struct sockaddr *) ai->ai_addr, ai->ai_addrlen, - sock_name, sizeof(sock_name), NULL, 0, NI_NUMERICHOST); - - switch (ai->ai_family) { - case AF_INET6: - ((struct sockaddr_in6 *) (ai->ai_addr))->sin6_port = - listen_port; - break; - case AF_INET: - ((struct sockaddr_in *) (ai->ai_addr))->sin_port = - listen_port; - break; - } - - ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, - &one, sizeof(one)); - if (ret != 0) { - cry_error("setsockopt: %s (%s)", strerror(errno), - sock_name); - return -1; - } - - ret = bind(listenfd, ai->ai_addr, ai->ai_addrlen); - if (ret != 0) { - cry_error("bind to %s failed: %s", sock_name, - strerror(errno)); - return -1; - } - - if (listen(listenfd, _CRYWRAP_MAXCONN) != 0) { - cry_error("listen on %s failed: %s", sock_name, - strerror(errno)); - return -1; - } - - cry_log("Socket bound to port %d on %s.", ntohs(listen_port), - sock_name); - - return listenfd; -} - -/** Set up a listening socket. - * Sets up a listening socket on all the required addresses. - * - * @param config holds the CryWrap configuration, from where the - * listen address and port will be extracted. - * - * @returns The listening FD on success, -1 on error. - */ -static int _crywrap_listen(const crywrap_config_t * config) -{ - struct addrinfo *cur; - int ret; - - cur = calloc(1, sizeof(struct addrinfo)); - if (cur == NULL) - return -1; - - cur->ai_family = config->listen.addr->ss_family; - - switch (cur->ai_family) { - case AF_INET6: - cur->ai_addrlen = sizeof(struct sockaddr_in6); - break; - case AF_INET: - cur->ai_addrlen = sizeof(struct sockaddr_in); - break; - default: - ret = -1; - goto cleanup; - } - - cur->ai_addr = malloc(cur->ai_addrlen); - if (cur->ai_addr == NULL) - return -1; - - memcpy(cur->ai_addr, config->listen.addr, cur->ai_addrlen); - - ret = _crywrap_bind(cur, htons(config->listen.port)); - free(cur->ai_addr); - - cleanup: - free(cur); - - return ret; -} - -/** Connect to a remote server. - * Estabilishes a connection to a remote server, and handles all - * errors and anything that may arise during this process. - * - * @param addr is the address of the remote server. - * @param port is the port to connect to. - * - * @returns the connected socket on success, otherwise it exits. - */ -static int -_crywrap_remote_connect(const struct sockaddr_storage *addr, int port) -{ - struct addrinfo *cur; - int sock; - - cur = calloc(1, sizeof(struct addrinfo)); - if (cur == NULL) - return -1; - - cur->ai_family = addr->ss_family; - - switch (cur->ai_family) { - case AF_INET6: - cur->ai_addrlen = sizeof(struct sockaddr_in6); - break; - case AF_INET: - cur->ai_addrlen = sizeof(struct sockaddr_in); - break; - default: - sock = -1; - goto cleanup; - } - - cur->ai_addr = malloc(cur->ai_addrlen); - if (cur->ai_addr == NULL) - return -1; - - memcpy(cur->ai_addr, addr, cur->ai_addrlen); - - switch (cur->ai_family) { - case AF_INET6: - ((struct sockaddr_in6 *) (cur->ai_addr))->sin6_port = port; - break; - case AF_INET: - ((struct sockaddr_in *) (cur->ai_addr))->sin_port = port; - break; - } - - sock = socket(cur->ai_family, SOCK_STREAM, IPPROTO_IP); - if (sock < 0) { - cry_error("socket(): %s", strerror(errno)); - exit(1); - } - - if (connect(sock, cur->ai_addr, cur->ai_addrlen) < 0) { - cry_error("connect(): %s", strerror(errno)); - exit(1); - } - - free(cur->ai_addr); - - cleanup: - free(cur); - - return sock; -} - -/** @} */ - -/** @defgroup crywrap Main CryWrap code. - * @{ - */ - -/** Drop privileges. - * Drop privileges, if running as root. - * Upon failure, it will make CryWrap exit. - */ -static void _crywrap_privs_drop(const crywrap_config_t * config) -{ - struct passwd *pwd; - - if (getuid() != 0) { - cry_log("%s", - "Not running as root, not dropping privileges."); - return; - } - - if ((pwd = getpwuid(config->uid)) == NULL) { - cry_error("getpwuid(): %s", strerror(errno)); - exit(1); - } - - if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { - cry_error("initgroups(): %s", strerror(errno)); - exit(1); - } - - if (setgid(pwd->pw_gid) == -1) { - cry_error("setgid(): %s", strerror(errno)); - exit(1); - } - - if (setuid(config->uid)) { - cry_error("setuid(): %s", strerror(errno)); - exit(1); - } -} - -/** Set up the PID file. - * Checks if a #pidfile already exists, and create one - containing the - * current PID - if one does not. - * - * @note Exits upon error. - */ -static void _crywrap_setup_pidfile(const crywrap_config_t * config) -{ - char mypid[128]; - int pidfilefd; - - if (!config->pidfile || !*(config->pidfile)) - return; - - if (!access(config->pidfile, F_OK)) { - cry_error("Pidfile (%s) already exists. Exiting.", - config->pidfile); - exit(1); - } - if ((pidfilefd = open(config->pidfile, - O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { - cry_error("Cannot create pidfile (%s): %s.\n", - config->pidfile, strerror(errno)); - exit(1); - } - fchown(pidfilefd, config->uid, (gid_t) - 1); - - main_pid = getpid(); - snprintf(mypid, sizeof(mypid), "%d\n", main_pid); - write(pidfilefd, mypid, strlen(mypid)); - close(pidfilefd); - pidfile = config->pidfile; -} - - -/** Handles one client. - * This one connects to the remote server, and proxies every traffic - * between our client and the server. - * - * @param config is the main CryWrap configuration structure. - * @param insock is the socket through which the client sends input. - * @param outsock is the socket through which we send output. - * - * @note Exits on error. - */ -static int -_crywrap_do_one(const crywrap_config_t * config, int insock, int outsock) -{ - int sock, ret, tls_pending; - gnutls_session_t session; - char buffer[_CRYWRAP_MAXBUF + 2]; - fd_set fdset; - unsigned int status = 0; - struct sockaddr_storage faddr; - socklen_t socklen = sizeof(struct sockaddr_storage); - char peer_name[NI_MAXHOST]; - - /* Log the connection */ - if (getpeername(insock, (struct sockaddr *) &faddr, &socklen) != 0) - cry_error("getpeername(): %s", strerror(errno)); - else { - getnameinfo((struct sockaddr *) &faddr, - sizeof(struct sockaddr_storage), peer_name, - sizeof(peer_name), NULL, 0, NI_NUMERICHOST); - cry_log("Accepted connection from %s on %d to %s/%d", - peer_name, insock, config->dest.host, - config->dest.port); - } - - /* Do the handshake with our peer */ - session = _crywrap_tls_session_create(config); - gnutls_transport_set_ptr2(session, - (gnutls_transport_ptr_t) insock, - (gnutls_transport_ptr_t) outsock); - - do { - ret = gnutls_handshake(session); - } - while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); - - if (ret < 0) { - cry_error("Handshake failed: %s", gnutls_strerror(ret)); - gnutls_alert_send_appropriate(session, ret); - goto error; - } - - /* Verify the client's certificate, if any. */ - if (config->verify) { - ret = gnutls_certificate_verify_peers2(session, &status); - if (ret < 0) - cry_log - ("Error getting certificate from client: %s", - gnutls_strerror(ret)); - - if (ret == 0 && status != 0) { - if (status & GNUTLS_CERT_INVALID) - cry_log("%s", - "Client certificate not trusted or invalid"); - } - - if (config->verify > 0 && status != 0) { - ret = -1; - gnutls_alert_send(session, GNUTLS_AL_FATAL, - GNUTLS_A_INSUFFICIENT_SECURITY); - goto error; - } - } - - /* Connect to the remote host */ - sock = _crywrap_remote_connect(config->dest.addr, - htons(config->dest.port)); - - for (;;) { - FD_ZERO(&fdset); - FD_SET(insock, &fdset); - FD_SET(sock, &fdset); - - memset(buffer, 0, _CRYWRAP_MAXBUF + 1); - - tls_pending = 0; - - if (gnutls_record_check_pending(session) > 0) - tls_pending = 1; - else { - select(sock + 1, &fdset, NULL, NULL, NULL); - if (FD_ISSET(insock, &fdset)) - tls_pending = 1; - } - /* TLS client */ - if (tls_pending != 0) { - ret = - gnutls_record_recv(session, buffer, - _CRYWRAP_MAXBUF); - if (ret == 0) { - cry_log("%s", - "Peer has closed the GNUTLS connection"); - break; - } else if (ret < 0) { - cry_log("Received corrupted data: %s.", - gnutls_strerror(ret)); - break; - } else - send(sock, buffer, ret, 0); - } - - /* Remote server */ - if (FD_ISSET(sock, &fdset)) { - ret = recv(sock, buffer, _CRYWRAP_MAXBUF, 0); - if (ret == 0) { - cry_log("%s", - "Server has closed the connection"); - break; - } else if (ret < 0) { - cry_log("Received corrupted data: %s.", - strerror(errno)); - break; - } else { - int r, o = 0; - - do { - r = gnutls_record_send(session, - &buffer[o], - ret - o); - o += r; - } while (r > 0 && ret > o); - - if (r < 0) - cry_log - ("Received corrupt data: %s", - gnutls_strerror(r)); - } - } - } - - error: - gnutls_bye(session, GNUTLS_SHUT_WR); - gnutls_deinit(session); - close(insock); - close(outsock); - - return (ret == 0) ? 0 : 1; -} - -/** CryWrap entry point. - * This is the main entry point - controls the whole program and so - * on... - */ -int main(int argc, char **argv, char **envp) -{ - crywrap_config_t *config; - int server_socket; - - openlog(__CRYWRAP__, LOG_PID, LOG_DAEMON); - - gnutls_global_set_audit_log_function(tls_audit_log_func); - - if (gnutls_global_init() < 0) { - cry_error("%s", "Global TLS state initialisation failed."); - exit(1); - } - if (gnutls_certificate_allocate_credentials(&cred) < 0) { - cry_error("%s", "Couldn't allocate credentials."); - exit(1); - } - - stringprep_locale_charset(); - - config = _crywrap_config_parse(argc, argv); - - _crywrap_tls_init(); - - if (config->inetd) { - _crywrap_privs_drop(config); - exit(_crywrap_do_one(config, 0, 1)); - } - - if (!config->debug) - if (daemon(0, 0)) { - cry_error("daemon: %s", strerror(errno)); - exit(1); - } - - cry_log("%s", "Crywrap starting..."); - - server_socket = _crywrap_listen(config); - if (server_socket < 0) - exit(1); - - if (!config->debug) - _crywrap_setup_pidfile(config); - _crywrap_privs_drop(config); - - signal(SIGTERM, _crywrap_sighandler); - signal(SIGQUIT, _crywrap_sighandler); - signal(SIGSEGV, _crywrap_sighandler); - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, SIG_IGN); - signal(SIGCHLD, _crywrap_sigchld_handler); - - cry_log("%s", "Accepting connections"); - - - for (;;) { - int csock; - int child; - - csock = accept(server_socket, NULL, NULL); - if (csock < 0) - continue; - - child = fork(); - switch (child) { - case 0: - exit(_crywrap_do_one(config, csock, csock)); - break; - case -1: - cry_error("%s", "Forking error."); - exit(1); - break; - } - close(csock); - } - - return 0; -} - -static int system_log(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vsyslog(LOG_NOTICE, fmt, args); - va_end(args); - - return 0; -} - -static int system_log_error(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vsyslog(LOG_ERR, fmt, args); - va_end(args); - - return 0; -} - -static int debug_log(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - puts(""); - va_end(args); - - return 0; -} - -/** @} */ diff --git a/src/crywrap/crywrap.h b/src/crywrap/crywrap.h deleted file mode 100644 index a41990f4a0..0000000000 --- a/src/crywrap/crywrap.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- mode: c; c-file-style: "gnu" -*- - * crywrap.h -- Global definitions for CryWrap - * Copyright (C) 2003, 2004 Gergely Nagy <algernon@bonehunter.rulez.org> - * - * This file is part of CryWrap. - * - * CryWrap is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CryWrap is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** @file crywrap.h - * Global variables and declarations for CryWrap. - * - * All of the global types, structures and whatnot are declared in - * this file. Not variables, though. Those are in crywrap.c. - */ - -#ifndef _CRYWRAP_H -#define _CRYWRAP_H 1 /**< crywrap.h multi-inclusion guard. */ - -/** @defgroup defaults Built-in defaults. - * @{ - */ -#define __CRYWRAP__ "crywrap" /**< Software name. */ -/** Software version. - */ -#define _CRYWRAP_VERSION "0.2." CRYWRAP_PATCHLEVEL -/** Configuration directory. - */ -#define _CRYWRAP_CONFDIR SYSCONFDIR "/crywrap" -#define _CRYWRAP_UID 65534 /**< Default UID to run as. */ -/** Default PID file. - */ -#define _CRYWRAP_PIDFILE "/var/run/crywrap.pid" -/** Maximum number of clients supported. - */ -#define _CRYWRAP_MAXCONN 1024 -/** Maximum I/O buffer size. - */ -#define _CRYWRAP_MAXBUF 64 * 1024 -/** Default server certificate and key. - */ -#define _CRYWRAP_PEMFILE _CRYWRAP_CONFDIR "/server.pem" -/** @} */ - -/** Configuration structure. - * Most of the CryWrap configuration - those options that are settable - * via the command-line are stored in a variable of this type. - */ -typedef struct { - /** Properties of the listening socket. - */ - struct { - in_port_t port; - struct sockaddr_storage *addr; - } listen; - - /** Properties of the destination socket. - */ - struct { - in_port_t port; - char *host; - struct sockaddr_storage *addr; - } dest; - - gnutls_priority_t priority; - /**< GnuTLS priority string. */ - const char *pidfile; - /**< File to store our PID in. */ - uid_t uid; - /**< User ID to run as. */ - int inetd; - /**< InetD-mode toggle. */ - int anon; - /**< Anon-DH toggle. */ - int verify; - /**< Client certificate verify level. */ - int debug; -} crywrap_config_t; - - /** @} *//* End of the Options group */ - -#endif /* !_CRYWRAP_H */ diff --git a/src/crywrap/primes.h b/src/crywrap/primes.h deleted file mode 100644 index 2ca1e1ad86..0000000000 --- a/src/crywrap/primes.h +++ /dev/null @@ -1,41 +0,0 @@ -/* primes.h -- initial DH primes for CryWrap - * - * Copyright (C) 2003 Gergely Nagy <algernon@bonehunter.rulez.org> - * Copyright (C) 2011 Nikos Mavrogiannopoulos - * - * This file is part of CryWrap. - * - * CryWrap is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * CryWrap is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** @file primes.h - * Initial DH primes for CryWrap. - * - * In order to speed up the startup time, CryWrap does not generate a - * new DH prime upon every startup, but only when it receives a - * SIGHUP. - */ - -#ifndef _CRYWRAP_PRIMES_H -#define _CRYWRAP_PRIMES_H - -/** Initial DH primes, 1024 bits. - */ -static char _crywrap_prime_dh_1024[] = "-----BEGIN DH PARAMETERS-----\n" - "MIGHAoGBAO6vCrmts43WnDP4CvqPxehgcmGHdf88C56iMUycJWV21nTfdJbqgdM4\n" - "O0gT1pLG4ODV2OJQuYvkjklcHWCJ2tFdx9e0YVTWts6O9K1psV1JglWbKXvPGIXF\n" - "KfVmZg5X7GjtvDwFcmzAL9TL9Jduqpr9UTj+g3ZDW5/GHS/A6wbjAgEC\n" - "-----END DH PARAMETERS-----\n"; - -#endif |