summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/kx/kxd.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/kx/kxd.c')
-rw-r--r--crypto/heimdal/appl/kx/kxd.c754
1 files changed, 0 insertions, 754 deletions
diff --git a/crypto/heimdal/appl/kx/kxd.c b/crypto/heimdal/appl/kx/kxd.c
deleted file mode 100644
index 65f6165..0000000
--- a/crypto/heimdal/appl/kx/kxd.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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 Institute 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 INSTITUTE 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 INSTITUTE 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.
- */
-
-#include "kx.h"
-
-RCSID("$Id: kxd.c,v 1.69 2001/02/20 01:44:45 assar Exp $");
-
-static pid_t wait_on_pid = -1;
-static int done = 0;
-
-/*
- * Signal handler that justs waits for the children when they die.
- */
-
-static RETSIGTYPE
-childhandler (int sig)
-{
- pid_t pid;
- int status;
-
- do {
- pid = waitpid (-1, &status, WNOHANG|WUNTRACED);
- if (pid > 0 && pid == wait_on_pid)
- done = 1;
- } while(pid > 0);
- signal (SIGCHLD, childhandler);
- SIGRETURN(0);
-}
-
-/*
- * Print the error message `format' and `...' on fd and die.
- */
-
-void
-fatal (kx_context *kc, int fd, char *format, ...)
-{
- u_char msg[1024];
- u_char *p;
- va_list args;
- int len;
-
- va_start(args, format);
- p = msg;
- *p++ = ERROR;
- vsnprintf ((char *)p + 4, sizeof(msg) - 5, format, args);
- syslog (LOG_ERR, "%s", (char *)p + 4);
- len = strlen ((char *)p + 4);
- p += KRB_PUT_INT (len, p, 4, 4);
- p += len;
- kx_write (kc, fd, msg, p - msg);
- va_end(args);
- exit (1);
-}
-
-/*
- * Remove all sockets and cookie files.
- */
-
-static void
-cleanup(int nsockets, struct x_socket *sockets)
-{
- int i;
-
- if(xauthfile[0])
- unlink(xauthfile);
- for (i = 0; i < nsockets; ++i) {
- if (sockets[i].pathname != NULL) {
- unlink (sockets[i].pathname);
- free (sockets[i].pathname);
- }
- }
-}
-
-/*
- * Prepare to receive a connection on `sock'.
- */
-
-static int
-recv_conn (int sock, kx_context *kc,
- int *dispnr, int *nsockets, struct x_socket **sockets,
- int tcp_flag)
-{
- u_char msg[1024], *p;
- char user[256];
- socklen_t addrlen;
- struct passwd *passwd;
- struct sockaddr_in thisaddr, thataddr;
- char remotehost[MaxHostNameLen];
- char remoteaddr[INET6_ADDRSTRLEN];
- int ret = 1;
- int flags;
- int len;
- u_int32_t tmp32;
-
- addrlen = sizeof(thisaddr);
- if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
- addrlen != sizeof(thisaddr)) {
- syslog (LOG_ERR, "getsockname: %m");
- exit (1);
- }
- addrlen = sizeof(thataddr);
- if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
- addrlen != sizeof(thataddr)) {
- syslog (LOG_ERR, "getpeername: %m");
- exit (1);
- }
-
- kc->thisaddr = thisaddr;
- kc->thataddr = thataddr;
-
- getnameinfo_verified ((struct sockaddr *)&thataddr, addrlen,
- remotehost, sizeof(remotehost),
- NULL, 0, 0);
-
- if (net_read (sock, msg, 4) != 4) {
- syslog (LOG_ERR, "read: %m");
- exit (1);
- }
-
-#ifdef KRB5
- if (ret && recv_v5_auth (kc, sock, msg) == 0)
- ret = 0;
-#endif
-#ifdef KRB4
- if (ret && recv_v4_auth (kc, sock, msg) == 0)
- ret = 0;
-#endif
- if (ret) {
- syslog (LOG_ERR, "unrecognized auth protocol: %x %x %x %x",
- msg[0], msg[1], msg[2], msg[3]);
- exit (1);
- }
-
- len = kx_read (kc, sock, msg, sizeof(msg));
- if (len < 0) {
- syslog (LOG_ERR, "kx_read failed");
- exit (1);
- }
- p = (u_char *)msg;
- if (*p != INIT)
- fatal(kc, sock, "Bad message");
- p++;
- p += krb_get_int (p, &tmp32, 4, 0);
- len = min(sizeof(user), tmp32);
- memcpy (user, p, len);
- p += tmp32;
- user[len] = '\0';
-
- passwd = k_getpwnam (user);
- if (passwd == NULL)
- fatal (kc, sock, "cannot find uid for %s", user);
-
- if (context_userok (kc, user) != 0)
- fatal (kc, sock, "%s not allowed to login as %s",
- kc->user, user);
-
- flags = *p++;
-
- if (flags & PASSIVE) {
- pid_t pid;
- int tmp;
-
- tmp = get_xsockets (nsockets, sockets, tcp_flag);
- if (tmp < 0) {
- fatal (kc, sock, "Cannot create X socket(s): %s",
- strerror(errno));
- }
- *dispnr = tmp;
-
- if (chown_xsockets (*nsockets, *sockets,
- passwd->pw_uid, passwd->pw_gid)) {
- cleanup (*nsockets, *sockets);
- fatal (kc, sock, "Cannot chown sockets: %s",
- strerror(errno));
- }
-
- pid = fork();
- if (pid == -1) {
- cleanup (*nsockets, *sockets);
- fatal (kc, sock, "fork: %s", strerror(errno));
- } else if (pid != 0) {
- wait_on_pid = pid;
- while (!done)
- pause ();
- cleanup (*nsockets, *sockets);
- exit (0);
- }
- }
-
- if (setgid (passwd->pw_gid) ||
- initgroups(passwd->pw_name, passwd->pw_gid) ||
-#ifdef HAVE_GETUDBNAM /* XXX this happens on crays */
- setjob(passwd->pw_uid, 0) == -1 ||
-#endif
- setuid(passwd->pw_uid)) {
- syslog(LOG_ERR, "setting uid/groups: %m");
- fatal (kc, sock, "cannot set uid");
- }
- inet_ntop (thataddr.sin_family,
- &thataddr.sin_addr, remoteaddr, sizeof(remoteaddr));
-
- syslog (LOG_INFO, "from %s(%s): %s -> %s",
- remotehost, remoteaddr,
- kc->user, user);
- umask(077);
- if (!(flags & PASSIVE)) {
- p += krb_get_int (p, &tmp32, 4, 0);
- len = min(tmp32, display_size);
- memcpy (display, p, len);
- display[len] = '\0';
- p += tmp32;
- p += krb_get_int (p, &tmp32, 4, 0);
- len = min(tmp32, xauthfile_size);
- memcpy (xauthfile, p, len);
- xauthfile[len] = '\0';
- p += tmp32;
- }
-#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
- if (flags & KEEP_ALIVE) {
- int one = 1;
-
- setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
- sizeof(one));
- }
-#endif
- return flags;
-}
-
-/*
- *
- */
-
-static int
-passive_session (kx_context *kc, int fd, int sock, int cookiesp)
-{
- if (verify_and_remove_cookies (fd, sock, cookiesp))
- return 1;
- else
- return copy_encrypted (kc, fd, sock);
-}
-
-/*
- *
- */
-
-static int
-active_session (kx_context *kc, int fd, int sock, int cookiesp)
-{
- fd = connect_local_xsocket(0);
-
- if (replace_cookie (fd, sock, xauthfile, cookiesp))
- return 1;
- else
- return copy_encrypted (kc, fd, sock);
-}
-
-/*
- * Handle a new connection.
- */
-
-static int
-doit_conn (kx_context *kc,
- int fd, int meta_sock, int flags, int cookiesp)
-{
- int sock, sock2;
- struct sockaddr_in addr;
- struct sockaddr_in thisaddr;
- socklen_t addrlen;
- u_char msg[1024], *p;
-
- sock = socket (AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- syslog (LOG_ERR, "socket: %m");
- return 1;
- }
-#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
- {
- int one = 1;
- setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
- }
-#endif
-#if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
- if (flags & KEEP_ALIVE) {
- int one = 1;
-
- setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one,
- sizeof(one));
- }
-#endif
- memset (&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- if (bind (sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- syslog (LOG_ERR, "bind: %m");
- return 1;
- }
- addrlen = sizeof(addr);
- if (getsockname (sock, (struct sockaddr *)&addr, &addrlen) < 0) {
- syslog (LOG_ERR, "getsockname: %m");
- return 1;
- }
- if (listen (sock, SOMAXCONN) < 0) {
- syslog (LOG_ERR, "listen: %m");
- return 1;
- }
- p = msg;
- *p++ = NEW_CONN;
- p += KRB_PUT_INT (ntohs(addr.sin_port), p, 4, 4);
-
- if (kx_write (kc, meta_sock, msg, p - msg) < 0) {
- syslog (LOG_ERR, "write: %m");
- return 1;
- }
-
- addrlen = sizeof(thisaddr);
- sock2 = accept (sock, (struct sockaddr *)&thisaddr, &addrlen);
- if (sock2 < 0) {
- syslog (LOG_ERR, "accept: %m");
- return 1;
- }
- close (sock);
- close (meta_sock);
-
- if (flags & PASSIVE)
- return passive_session (kc, fd, sock2, cookiesp);
- else
- return active_session (kc, fd, sock2, cookiesp);
-}
-
-/*
- * Is the current user the owner of the console?
- */
-
-static void
-check_user_console (kx_context *kc, int fd)
-{
- struct stat sb;
-
- if (stat ("/dev/console", &sb) < 0)
- fatal (kc, fd, "Cannot stat /dev/console: %s", strerror(errno));
- if (getuid() != sb.st_uid)
- fatal (kc, fd, "Permission denied");
-}
-
-/* close down the new connection with a reasonable error message */
-static void
-close_connection(int fd, const char *message)
-{
- char buf[264]; /* max message */
- char *p;
- int lsb = 0;
- size_t mlen;
-
- mlen = strlen(message);
- if(mlen > 255)
- mlen = 255;
-
- /* read first part of connection packet, to get byte order */
- if(read(fd, buf, 6) != 6) {
- close(fd);
- return;
- }
- if(buf[0] == 0x6c)
- lsb++;
- p = buf;
- *p++ = 0; /* failed */
- *p++ = mlen; /* length of message */
- p += 4; /* skip protocol version */
- p += 2; /* skip additional length */
- memcpy(p, message, mlen); /* copy message */
- p += mlen;
- while((p - buf) % 4) /* pad to multiple of 4 bytes */
- *p++ = 0;
-
- /* now fill in length of additional data */
- if(lsb) {
- buf[6] = (p - buf - 8) / 4;
- buf[7] = 0;
- }else{
- buf[6] = 0;
- buf[7] = (p - buf - 8) / 4;
- }
- write(fd, buf, p - buf);
- close(fd);
-}
-
-
-/*
- * Handle a passive session on `sock'
- */
-
-static int
-doit_passive (kx_context *kc,
- int sock,
- int flags,
- int dispnr,
- int nsockets,
- struct x_socket *sockets,
- int tcp_flag)
-{
- int tmp;
- int len;
- size_t rem;
- u_char msg[1024], *p;
- int error;
-
- display_num = dispnr;
- if (tcp_flag)
- snprintf (display, display_size, "localhost:%u", display_num);
- else
- snprintf (display, display_size, ":%u", display_num);
- error = create_and_write_cookie (xauthfile, xauthfile_size,
- cookie, cookie_len);
- if (error) {
- cleanup(nsockets, sockets);
- fatal (kc, sock, "Cookie-creation failed: %s", strerror(error));
- return 1;
- }
-
- p = msg;
- rem = sizeof(msg);
- *p++ = ACK;
- --rem;
-
- len = strlen (display);
- tmp = KRB_PUT_INT (len, p, rem, 4);
- if (tmp < 0 || rem < len + 4) {
- syslog (LOG_ERR, "doit: buffer too small");
- cleanup(nsockets, sockets);
- return 1;
- }
- p += tmp;
- rem -= tmp;
-
- memcpy (p, display, len);
- p += len;
- rem -= len;
-
- len = strlen (xauthfile);
- tmp = KRB_PUT_INT (len, p, rem, 4);
- if (tmp < 0 || rem < len + 4) {
- syslog (LOG_ERR, "doit: buffer too small");
- cleanup(nsockets, sockets);
- return 1;
- }
- p += tmp;
- rem -= tmp;
-
- memcpy (p, xauthfile, len);
- p += len;
- rem -= len;
-
- if(kx_write (kc, sock, msg, p - msg) < 0) {
- syslog (LOG_ERR, "write: %m");
- cleanup(nsockets, sockets);
- return 1;
- }
- for (;;) {
- pid_t child;
- int fd = -1;
- fd_set fds;
- int i;
- int ret;
- int cookiesp = TRUE;
-
- FD_ZERO(&fds);
- if (sock >= FD_SETSIZE) {
- syslog (LOG_ERR, "fd too large");
- cleanup(nsockets, sockets);
- return 1;
- }
-
- FD_SET(sock, &fds);
- for (i = 0; i < nsockets; ++i) {
- if (sockets[i].fd >= FD_SETSIZE) {
- syslog (LOG_ERR, "fd too large");
- cleanup(nsockets, sockets);
- return 1;
- }
- FD_SET(sockets[i].fd, &fds);
- }
- ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
- if(ret <= 0)
- continue;
- if(FD_ISSET(sock, &fds)){
- /* there are no processes left on the remote side
- */
- cleanup(nsockets, sockets);
- exit(0);
- } else if(ret) {
- for (i = 0; i < nsockets; ++i) {
- if (FD_ISSET(sockets[i].fd, &fds)) {
- if (sockets[i].flags == TCP) {
- struct sockaddr_in peer;
- socklen_t len = sizeof(peer);
-
- fd = accept (sockets[i].fd,
- (struct sockaddr *)&peer,
- &len);
- if (fd < 0 && errno != EINTR)
- syslog (LOG_ERR, "accept: %m");
-
- /* XXX */
- if (fd >= 0 && suspicious_address (fd, peer)) {
- close (fd);
- fd = -1;
- errno = EINTR;
- }
- } else if(sockets[i].flags == UNIX_SOCKET) {
- socklen_t zero = 0;
-
- fd = accept (sockets[i].fd, NULL, &zero);
-
- if (fd < 0 && errno != EINTR)
- syslog (LOG_ERR, "accept: %m");
-#ifdef MAY_HAVE_X11_PIPES
- } else if(sockets[i].flags == STREAM_PIPE) {
- /*
- * this code tries to handle the
- * send fd-over-pipe stuff for
- * solaris
- */
-
- struct strrecvfd strrecvfd;
-
- ret = ioctl (sockets[i].fd,
- I_RECVFD, &strrecvfd);
- if (ret < 0 && errno != EINTR) {
- syslog (LOG_ERR, "ioctl I_RECVFD: %m");
- }
-
- /* XXX */
- if (ret == 0) {
- if (strrecvfd.uid != getuid()) {
- close (strrecvfd.fd);
- fd = -1;
- errno = EINTR;
- } else {
- fd = strrecvfd.fd;
- cookiesp = FALSE;
- }
- }
-#endif /* MAY_HAVE_X11_PIPES */
- } else
- abort ();
- break;
- }
- }
- }
- if (fd < 0) {
- if (errno == EINTR)
- continue;
- else
- return 1;
- }
-
- child = fork ();
- if (child < 0) {
- syslog (LOG_ERR, "fork: %m");
- if(errno != EAGAIN)
- return 1;
- close_connection(fd, strerror(errno));
- } else if (child == 0) {
- for (i = 0; i < nsockets; ++i)
- close (sockets[i].fd);
- return doit_conn (kc, fd, sock, flags, cookiesp);
- } else {
- close (fd);
- }
- }
-}
-
-/*
- * Handle an active session on `sock'
- */
-
-static int
-doit_active (kx_context *kc,
- int sock,
- int flags,
- int tcp_flag)
-{
- u_char msg[1024], *p;
-
- check_user_console (kc, sock);
-
- p = msg;
- *p++ = ACK;
-
- if(kx_write (kc, sock, msg, p - msg) < 0) {
- syslog (LOG_ERR, "write: %m");
- return 1;
- }
- for (;;) {
- pid_t child;
- int len;
-
- len = kx_read (kc, sock, msg, sizeof(msg));
- if (len < 0) {
- syslog (LOG_ERR, "read: %m");
- return 1;
- }
- p = (u_char *)msg;
- if (*p != NEW_CONN) {
- syslog (LOG_ERR, "bad_message: %d", *p);
- return 1;
- }
-
- child = fork ();
- if (child < 0) {
- syslog (LOG_ERR, "fork: %m");
- if (errno != EAGAIN)
- return 1;
- } else if (child == 0) {
- return doit_conn (kc, sock, sock, flags, 1);
- } else {
- }
- }
-}
-
-/*
- * Receive a connection on `sock' and process it.
- */
-
-static int
-doit(int sock, int tcp_flag)
-{
- int ret;
- kx_context context;
- int dispnr;
- int nsockets;
- struct x_socket *sockets;
- int flags;
-
- flags = recv_conn (sock, &context, &dispnr, &nsockets, &sockets, tcp_flag);
-
- if (flags & PASSIVE)
- ret = doit_passive (&context, sock, flags, dispnr,
- nsockets, sockets, tcp_flag);
- else
- ret = doit_active (&context, sock, flags, tcp_flag);
- context_destroy (&context);
- return ret;
-}
-
-static char *port_str = NULL;
-static int inetd_flag = 1;
-static int tcp_flag = 0;
-static int version_flag = 0;
-static int help_flag = 0;
-
-struct getargs args[] = {
- { "inetd", 'i', arg_negative_flag, &inetd_flag,
- "Not started from inetd" },
- { "tcp", 't', arg_flag, &tcp_flag, "Use TCP" },
- { "port", 'p', arg_string, &port_str, "Use this port",
- "port" },
- { "version", 0, arg_flag, &version_flag },
- { "help", 0, arg_flag, &help_flag }
-};
-
-static void
-usage(int ret)
-{
- arg_printusage (args,
- sizeof(args) / sizeof(args[0]),
- NULL,
- "host");
- exit (ret);
-}
-
-/*
- * kxd - receive a forwarded X conncection
- */
-
-int
-main (int argc, char **argv)
-{
- int port;
- int optind = 0;
-
- setprogname (argv[0]);
- roken_openlog ("kxd", LOG_ODELAY | LOG_PID, LOG_DAEMON);
-
- if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
- &optind))
- usage (1);
-
- if (help_flag)
- usage (0);
-
- if (version_flag) {
- print_version (NULL);
- return 0;
- }
-
- if(port_str) {
- struct servent *s = roken_getservbyname (port_str, "tcp");
-
- if (s)
- port = s->s_port;
- else {
- char *ptr;
-
- port = strtol (port_str, &ptr, 10);
- if (port == 0 && ptr == port_str)
- errx (1, "bad port `%s'", port_str);
- port = htons(port);
- }
- } else {
-#if defined(KRB5)
- port = krb5_getportbyname(NULL, "kx", "tcp", KX_PORT);
-#elif defined(KRB4)
- port = k_getportbyname ("kx", "tcp", htons(KX_PORT));
-#else
-#error define KRB4 or KRB5
-#endif
- }
-
- if (!inetd_flag)
- mini_inetd (port);
-
- signal (SIGCHLD, childhandler);
- return doit(STDIN_FILENO, tcp_flag);
-}
OpenPOWER on IntegriCloud