Files
heimdal/appl/kx/kxd.c
Assar Westerlund 4b262d0173 new program to forward x connections
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@393 ec53bebd-3082-4978-b11e-865c3cabbd6b
1996-04-14 19:31:57 +00:00

146 lines
3.4 KiB
C

#include "kx.h"
RCSID("$Id$");
static int
fatal (int fd, char *s)
{
u_char err = 1;
write (fd, &err, sizeof(err));
write (fd, s, strlen(s)+1);
return err;
}
static int
doit(int sock)
{
int status;
KTEXT_ST ticket;
AUTH_DAT auth;
char instance[INST_SZ + 1];
des_key_schedule schedule;
struct sockaddr_in thisaddr, thataddr;
int addrlen;
int len;
char buf[BUFSIZ];
void *data;
struct passwd *passwd;
char version[KRB_SENDAUTH_VLEN];
int fd;
struct stat sb;
struct sockaddr_un addr;
char *username;
des_cblock iv1, iv2;
int num1 = 0, num2 = 0;
unsigned dnr;
addrlen = sizeof(thisaddr);
if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) {
return 1;
}
addrlen = sizeof(thataddr);
if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
addrlen != sizeof(thataddr)) {
return 1;
}
k_getsockinst (sock, instance);
status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
&thataddr, &thisaddr, &auth, "", schedule,
version);
if (status != KSUCCESS ||
strncmp(version, "KXSERV.0", KRB_SENDAUTH_VLEN) != 0) {
return 1;
}
{
u_char b;
if (read (sock, &b, sizeof(b)) != sizeof(b))
return 1;
dnr = b;
}
if (stat ("/dev/console", &sb) < 0)
return fatal (fd, "Cannot stat /dev/console");
passwd = getpwuid (sb.st_uid);
if (passwd == NULL)
return fatal (fd, "Cannot find uid");
username = strdup (passwd->pw_name);
if (kuserok(&auth, username) != 0)
return fatal (fd, "Permission denied");
free (username);
if (setgid (passwd->pw_gid) ||
initgroups(passwd->pw_name, passwd->pw_gid) ||
setuid(passwd->pw_uid)) {
return fatal (fd, "Cannot set uid");
}
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return fatal (fd, "Cannot create socket");
addr.sun_family = AF_UNIX;
sprintf (addr.sun_path, "/tmp/.X11-unix/X%u", dnr);
if (connect (fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
return fatal (fd, "Cannot connect");
memcpy (&iv1, &auth.session, sizeof(iv1));
memcpy (&iv2, &auth.session, sizeof(iv2));
{
u_char b = 0;
if (write (sock, &b, sizeof(b)) != sizeof(b))
return 1;
}
for (;;) {
fd_set fdset;
int ret;
char buf[BUFSIZ];
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
FD_SET(fd, &fdset);
ret = select (fd+1, &fdset, NULL, NULL, NULL);
if (ret < 0 && errno != EINTR)
return 1;
if (FD_ISSET(sock, &fdset)) {
ret = read (sock, buf, sizeof(buf));
if (ret == 0)
return 0;
if (ret < 0)
return 1;
#ifndef NOENCRYPTION
des_cfb64_encrypt (buf, buf, ret, schedule,
&iv1, &num1, DES_DECRYPT);
#endif
ret = krb_net_write (fd, buf, ret);
if (ret < 0)
return 1;
}
if (FD_ISSET(fd, &fdset)) {
ret = read (fd, buf, sizeof(buf));
if (ret == 0)
return 0;
if (ret < 0)
return 1;
#ifndef NOENCRYPTION
des_cfb64_encrypt (buf, buf, ret, schedule,
&iv2, &num2, DES_ENCRYPT);
#endif
ret = krb_net_write (STDOUT_FILENO, buf, ret);
if (ret < 0)
return 1;
}
}
}
/*
* xkd - receive a forwarded X conncection
*/
int
main (int argc, char **argv)
{
return doit(0);
}