merged in TCP-branch
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@763 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
109
appl/kx/common.c
109
appl/kx/common.c
@@ -85,56 +85,109 @@ childhandler (int sig)
|
||||
SIGRETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and listen on a local X server socket.
|
||||
*/
|
||||
|
||||
#define TMPX11 "/tmp/.X11-unix"
|
||||
#ifndef X_UNIX_PATH
|
||||
#define X_UNIX_PATH "/tmp/.X11-unix/X"
|
||||
#endif
|
||||
|
||||
char x_socket[MaxPathLen];
|
||||
|
||||
/*
|
||||
* Allocate and listen on a local X server socket and a TCP socket.
|
||||
* Return the display number.
|
||||
*/
|
||||
|
||||
int
|
||||
get_local_xsocket (int *num)
|
||||
get_xsockets (int *unix_socket, int *tcp_socket)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_un addr;
|
||||
int unixfd, tcpfd;
|
||||
struct sockaddr_un unixaddr;
|
||||
struct sockaddr_in tcpaddr;
|
||||
int dpy;
|
||||
int oldmask;
|
||||
struct hostent *h;
|
||||
struct in_addr local;
|
||||
char *dir, *p;
|
||||
|
||||
dir = strdup (X_UNIX_PATH);
|
||||
p = strchr (dir, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
||||
oldmask = umask(0);
|
||||
mkdir (TMPX11, 01777);
|
||||
mkdir (dir, 01777);
|
||||
umask (oldmask);
|
||||
free (dir);
|
||||
|
||||
h = gethostbyname ("localhost");
|
||||
if (h)
|
||||
memcpy (&local, h->h_addr, h->h_length);
|
||||
else
|
||||
local.s_addr = inet_addr ("127.0.0.1");
|
||||
|
||||
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
fprintf (stderr, "%s: socket: %s\n", prog, strerror(errno));
|
||||
return fd;
|
||||
}
|
||||
addr.sun_family = AF_UNIX;
|
||||
for(dpy = 4; dpy < 256; ++dpy) {
|
||||
struct stat statbuf;
|
||||
unixfd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||
if (unixfd < 0) {
|
||||
fprintf (stderr, "%s: socket: %s\n", prog, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memset (&unixaddr, 0, sizeof(unixaddr));
|
||||
unixaddr.sun_family = AF_UNIX;
|
||||
sprintf (unixaddr.sun_path, X_UNIX_PATH "%u", dpy);
|
||||
if(bind(unixfd,
|
||||
(struct sockaddr *)&unixaddr,
|
||||
sizeof(unixaddr)) < 0) {
|
||||
close (unixfd);
|
||||
if (errno == EADDRINUSE ||
|
||||
errno == EACCES) /* Cray return EACCESS */
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf (addr.sun_path, TMPX11 "/X%u", dpy);
|
||||
if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||
if (errno == EADDRINUSE)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
else
|
||||
break;
|
||||
if (tcp_socket) {
|
||||
tcpfd = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (tcpfd < 0) {
|
||||
fprintf (stderr, "%s: socket: %s\n", prog,
|
||||
strerror(errno));
|
||||
close (unixfd);
|
||||
return -1;
|
||||
}
|
||||
memset (&tcpaddr, 0, sizeof(tcpaddr));
|
||||
tcpaddr.sin_family = AF_INET;
|
||||
tcpaddr.sin_addr = local;
|
||||
tcpaddr.sin_port = htons(6000 + dpy);
|
||||
if (bind (tcpfd, (struct sockaddr *)&tcpaddr,
|
||||
sizeof(tcpaddr)) < 0) {
|
||||
close (unixfd);
|
||||
close (tcpfd);
|
||||
if (errno == EADDRINUSE)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (dpy == 256) {
|
||||
fprintf (stderr, "%s: no free x-servers\n", prog);
|
||||
return -1;
|
||||
}
|
||||
if (listen (fd, SOMAXCONN) < 0) {
|
||||
if (listen (unixfd, SOMAXCONN) < 0) {
|
||||
fprintf (stderr, "%s: listen: %s\n", prog,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
strcpy(x_socket, addr.sun_path);
|
||||
*num = dpy;
|
||||
return fd;
|
||||
if (tcp_socket)
|
||||
if (listen (tcpfd, SOMAXCONN) < 0) {
|
||||
fprintf (stderr, "%s: listen: %s\n", prog,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
strcpy(x_socket, unixaddr.sun_path);
|
||||
*unix_socket = unixfd;
|
||||
if (tcp_socket)
|
||||
*tcp_socket = tcpfd;
|
||||
return dpy;
|
||||
}
|
||||
|
||||
/*
|
||||
|
20
appl/kx/kx.c
20
appl/kx/kx.c
@@ -41,7 +41,7 @@ connect_host (char *host, des_cblock *key, des_key_schedule schedule,
|
||||
|
||||
memset (&thataddr, 0, sizeof(thataddr));
|
||||
thataddr.sin_family = AF_INET;
|
||||
thataddr.sin_port = k_getportbyname ("kx", "tcp", htons(2111));
|
||||
thataddr.sin_port = k_getportbyname ("kx", "tcp", htons(KX_PORT));
|
||||
memcpy (&thataddr.sin_addr, hostent->h_addr, sizeof(thataddr.sin_addr));
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, 0);
|
||||
@@ -261,11 +261,15 @@ doit (char *host, int passivep)
|
||||
fprintf (stderr, "%s: listen: %s\n", prog, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (krb_net_write (otherside, &newaddr.sin_port,
|
||||
sizeof(newaddr.sin_port))
|
||||
!= sizeof(newaddr.sin_port)) {
|
||||
fprintf (stderr, "%s: write: %s\n", prog, strerror(errno));
|
||||
return 1;
|
||||
{
|
||||
char tmp[6];
|
||||
|
||||
sprintf (tmp, "%d", ntohs(newaddr.sin_port));
|
||||
if (krb_net_write (otherside, tmp, sizeof(tmp))
|
||||
!= sizeof(tmp)) {
|
||||
fprintf (stderr, "%s: write: %s\n", prog, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* close (otherside); */
|
||||
fn = passive;
|
||||
@@ -280,8 +284,8 @@ doit (char *host, int passivep)
|
||||
fclose(stdout);
|
||||
}
|
||||
} else {
|
||||
rendez_vous = get_local_xsocket (&display_num); /* XXX */
|
||||
if (rendez_vous < 0)
|
||||
display_num = get_xsockets (&rendez_vous, NULL);
|
||||
if (display_num < 0)
|
||||
return 1;
|
||||
fn = active;
|
||||
}
|
||||
|
31
appl/kx/kx.h
31
appl/kx/kx.h
@@ -11,21 +11,44 @@
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xauth.h>
|
||||
|
||||
#include <krb.h>
|
||||
@@ -36,10 +59,6 @@
|
||||
#define max(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef SOMAXCONN
|
||||
#define SOMAXCONN 5
|
||||
#endif
|
||||
|
||||
#ifndef LOG_DAEMON
|
||||
#define openlog(id,option,facility) openlog((id),(option))
|
||||
#endif
|
||||
@@ -53,5 +72,7 @@ RETSIGTYPE childhandler (int);
|
||||
|
||||
extern char x_socket[];
|
||||
|
||||
int get_local_xsocket (int *num);
|
||||
int get_xsockets (int *unix_socket, int *tcp_socket);
|
||||
int connect_local_xsocket (unsigned dnr);
|
||||
|
||||
#define KX_PORT 2111
|
||||
|
118
appl/kx/kxd.c
118
appl/kx/kxd.c
@@ -161,6 +161,10 @@ check_user_console ()
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef INADDR_LOOPBACK
|
||||
#define INADDR_LOOPBACK 0x7f000001
|
||||
#endif
|
||||
|
||||
static int
|
||||
create_and_write_cookie (char *xauthfile,
|
||||
u_char *cookie,
|
||||
@@ -170,9 +174,13 @@ create_and_write_cookie (char *xauthfile,
|
||||
char tmp[64];
|
||||
FILE *f;
|
||||
char hostname[MaxHostNameLen];
|
||||
struct in_addr loopback;
|
||||
struct hostent *h;
|
||||
|
||||
auth.family = FamilyLocal;
|
||||
k_gethostname (hostname, sizeof(hostname));
|
||||
loopback.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
auth.family = FamilyLocal;
|
||||
auth.address = hostname;
|
||||
auth.address_length = strlen(auth.address);
|
||||
sprintf (tmp, "%d", display_num);
|
||||
@@ -190,19 +198,61 @@ create_and_write_cookie (char *xauthfile,
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
h = gethostbyname (hostname);
|
||||
if (h == NULL) {
|
||||
fclose (f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* I would like to write a cookie for localhost:n here, but some
|
||||
* stupid code in libX11 will not look for cookies of that type,
|
||||
* so we are forced to use FamilyWild instead.
|
||||
*/
|
||||
|
||||
auth.family = FamilyWild;
|
||||
auth.address_length = 0;
|
||||
|
||||
#if 0 /* XXX */
|
||||
auth.address = (char *)&loopback;
|
||||
auth.address_length = sizeof(loopback);
|
||||
#endif
|
||||
|
||||
if (XauWriteAuth(f, &auth) == 0) {
|
||||
fclose (f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(fclose(f))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some simple controls on the address and corresponding socket
|
||||
*/
|
||||
|
||||
static int
|
||||
doit(int sock)
|
||||
suspicious_address (int sock, struct sockaddr_in addr)
|
||||
{
|
||||
char data[40];
|
||||
int len = sizeof(data);
|
||||
|
||||
|
||||
return addr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
|
||||
|| getsockopt (sock, IPPROTO_IP, IP_OPTIONS, data, &len) < 0
|
||||
|| len != 0;
|
||||
}
|
||||
|
||||
static int
|
||||
doit(int sock, int tcpp)
|
||||
{
|
||||
u_char passivep;
|
||||
struct sockaddr_in thataddr;
|
||||
des_key_schedule schedule;
|
||||
des_cblock key;
|
||||
int localx;
|
||||
int localx, tcpx;
|
||||
u_int32_t tmp;
|
||||
|
||||
if (recv_conn (sock, &key, schedule, &thataddr))
|
||||
@@ -212,8 +262,8 @@ doit(int sock)
|
||||
if (passivep) {
|
||||
char tmp[16];
|
||||
|
||||
localx = get_local_xsocket (&display_num);
|
||||
if (localx < 0)
|
||||
display_num = get_xsockets (&localx, tcpp ? &tcpx : NULL);
|
||||
if (display_num < 0)
|
||||
return 1;
|
||||
sprintf (tmp, "%u", display_num);
|
||||
if (krb_net_write (sock, tmp, sizeof(tmp)) != sizeof(tmp))
|
||||
@@ -225,9 +275,13 @@ doit(int sock)
|
||||
if(create_and_write_cookie (xauthfile, cookie,
|
||||
sizeof(cookie)))
|
||||
return 1;
|
||||
if (krb_net_read (sock, &thataddr.sin_port, sizeof(thataddr.sin_port))
|
||||
!= sizeof(thataddr.sin_port))
|
||||
return 1;
|
||||
{
|
||||
char tmp[6];
|
||||
|
||||
if(krb_net_read(sock, tmp, sizeof(tmp)) != sizeof(tmp))
|
||||
return -1;
|
||||
thataddr.sin_port = htons(atoi(tmp));
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
pid_t child;
|
||||
@@ -238,6 +292,8 @@ doit(int sock)
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(localx, &fds);
|
||||
FD_SET(sock, &fds);
|
||||
if (tcpp)
|
||||
FD_SET(tcpx, &fds);
|
||||
if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) <=0)
|
||||
continue;
|
||||
if(FD_ISSET(sock, &fds)){
|
||||
@@ -245,9 +301,19 @@ doit(int sock)
|
||||
*/
|
||||
cleanup();
|
||||
exit(0);
|
||||
}else if(FD_ISSET(localx, &fds))
|
||||
} else if(FD_ISSET(localx, &fds))
|
||||
fd = accept (localx, NULL, &zero);
|
||||
else
|
||||
else if(tcpp && FD_ISSET(tcpx, &fds)) {
|
||||
struct sockaddr_in peer;
|
||||
int len = sizeof(peer);
|
||||
|
||||
fd = accept (tcpx, (struct sockaddr *)&peer, &len);
|
||||
/* XXX */
|
||||
if (fd >= 0 && suspicious_address (fd, peer)) {
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
if (fd < 0)
|
||||
if (errno == EINTR)
|
||||
@@ -264,6 +330,8 @@ doit(int sock)
|
||||
return fatal(sock, msg);
|
||||
} else if (child == 0) {
|
||||
close (localx);
|
||||
if (tcpp)
|
||||
close (tcpx);
|
||||
return doit_conn (fd, &thataddr, &key, schedule);
|
||||
} else {
|
||||
close (fd);
|
||||
@@ -280,6 +348,13 @@ doit(int sock)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-i] [-t]\n", prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* xkd - receive a forwarded X conncection
|
||||
*/
|
||||
@@ -287,9 +362,30 @@ doit(int sock)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int no_inetd = 0;
|
||||
int tcpp = 0;
|
||||
|
||||
prog = argv[0];
|
||||
|
||||
while( (c = getopt (argc, argv, "it")) != EOF) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
no_inetd = 1;
|
||||
break;
|
||||
case 't':
|
||||
tcpp = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
fprintf (stderr, "%s: unknown option '%c'\n", prog, c);
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
if (no_inetd)
|
||||
mini_inetd (k_getportbyname("kx", "tcp", htons(KX_PORT)));
|
||||
openlog(prog, LOG_PID|LOG_CONS, LOG_DAEMON);
|
||||
signal (SIGCHLD, childhandler);
|
||||
return doit(0);
|
||||
return doit(STDIN_FILENO, tcpp);
|
||||
}
|
||||
|
Reference in New Issue
Block a user