2 * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static pid_t wait_on_pid
= -1;
42 * Signal handler that justs waits for the children when they die.
46 childhandler (int sig
)
52 pid
= waitpid (-1, &status
, WNOHANG
|WUNTRACED
);
53 if (pid
> 0 && pid
== wait_on_pid
)
56 signal (SIGCHLD
, childhandler
);
61 * Print the error message `format' and `...' on fd and die.
65 fatal (kx_context
*kc
, int fd
, char *format
, ...)
72 va_start(args
, format
);
75 vsnprintf ((char *)p
+ 4, sizeof(msg
) - 5, format
, args
);
76 syslog (LOG_ERR
, "%s", (char *)p
+ 4);
77 len
= strlen ((char *)p
+ 4);
78 p
+= kx_put_int (len
, p
, 4, 4);
80 kx_write (kc
, fd
, msg
, p
- msg
);
86 * Remove all sockets and cookie files.
90 cleanup(int nsockets
, struct x_socket
*sockets
)
96 for (i
= 0; i
< nsockets
; ++i
) {
97 if (sockets
[i
].pathname
!= NULL
) {
98 unlink (sockets
[i
].pathname
);
99 free (sockets
[i
].pathname
);
105 * Prepare to receive a connection on `sock'.
109 recv_conn (int sock
, kx_context
*kc
,
110 int *dispnr
, int *nsockets
, struct x_socket
**sockets
,
113 u_char msg
[1024], *p
;
116 struct passwd
*passwd
;
117 char remotehost
[MaxHostNameLen
];
118 char remoteaddr
[INET6_ADDRSTRLEN
];
124 memset(kc
, 0, sizeof(*kc
));
129 addrlen
= sizeof(kc
->__ss_this
);
130 kc
->thisaddr
= (struct sockaddr
*)&kc
->__ss_this
;
131 if (getsockname (sock
, kc
->thisaddr
, &addrlen
) < 0) {
132 syslog (LOG_ERR
, "getsockname: %m");
135 kc
->thisaddr_len
= addrlen
;
136 addrlen
= sizeof(kc
->__ss_that
);
137 kc
->thataddr
= (struct sockaddr
*)&kc
->__ss_that
;
138 if (getpeername (sock
, kc
->thataddr
, &addrlen
) < 0) {
139 syslog (LOG_ERR
, "getpeername: %m");
142 kc
->thataddr_len
= addrlen
;
144 getnameinfo_verified (kc
->thataddr
,
146 remotehost
, sizeof(remotehost
),
149 if (net_read (sock
, msg
, 4) != 4) {
150 syslog (LOG_ERR
, "read: %m");
155 if (ret
&& recv_v5_auth (kc
, sock
, msg
) == 0)
159 if (ret
&& recv_v4_auth (kc
, sock
, msg
) == 0)
163 syslog (LOG_ERR
, "unrecognized auth protocol: %x %x %x %x",
164 msg
[0], msg
[1], msg
[2], msg
[3]);
168 len
= kx_read (kc
, sock
, msg
, sizeof(msg
));
170 syslog (LOG_ERR
, "kx_read failed");
175 fatal(kc
, sock
, "Bad message");
177 p
+= kx_get_int (p
, &tmp32
, 4, 0);
178 len
= min(sizeof(user
), tmp32
);
179 memcpy (user
, p
, len
);
183 passwd
= k_getpwnam (user
);
185 fatal (kc
, sock
, "cannot find uid for %s", user
);
187 if (context_userok (kc
, user
) != 0)
188 fatal (kc
, sock
, "%s not allowed to login as %s",
193 if (flags
& PASSIVE
) {
197 tmp
= get_xsockets (nsockets
, sockets
, tcp_flag
);
199 fatal (kc
, sock
, "Cannot create X socket(s): %s",
204 if (chown_xsockets (*nsockets
, *sockets
,
205 passwd
->pw_uid
, passwd
->pw_gid
)) {
206 cleanup (*nsockets
, *sockets
);
207 fatal (kc
, sock
, "Cannot chown sockets: %s",
213 cleanup (*nsockets
, *sockets
);
214 fatal (kc
, sock
, "fork: %s", strerror(errno
));
215 } else if (pid
!= 0) {
219 cleanup (*nsockets
, *sockets
);
224 if (setgid (passwd
->pw_gid
) ||
225 initgroups(passwd
->pw_name
, passwd
->pw_gid
) ||
226 #ifdef HAVE_GETUDBNAM /* XXX this happens on crays */
227 setjob(passwd
->pw_uid
, 0) == -1 ||
229 setuid(passwd
->pw_uid
)) {
230 syslog(LOG_ERR
, "setting uid/groups: %m");
231 fatal (kc
, sock
, "cannot set uid");
234 ret
= getnameinfo(kc
->thataddr
, kc
->thataddr_len
,
235 remoteaddr
, sizeof(remoteaddr
),
236 NULL
, 0, NI_NUMERICHOST
);
238 fatal (kc
, sock
, "getnameinfo failed: %s", gai_strerror(ret
));
240 syslog (LOG_INFO
, "from %s(%s): %s -> %s",
241 remotehost
, remoteaddr
,
244 if (!(flags
& PASSIVE
)) {
245 p
+= kx_get_int (p
, &tmp32
, 4, 0);
246 len
= min(tmp32
, display_size
);
247 memcpy (display
, p
, len
);
250 p
+= kx_get_int (p
, &tmp32
, 4, 0);
251 len
= min(tmp32
, xauthfile_size
);
252 memcpy (xauthfile
, p
, len
);
253 xauthfile
[len
] = '\0';
256 #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
257 if (flags
& KEEP_ALIVE
) {
260 setsockopt (sock
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&one
,
272 passive_session (kx_context
*kc
, int fd
, int sock
, int cookiesp
)
274 if (verify_and_remove_cookies (fd
, sock
, cookiesp
))
277 return copy_encrypted (kc
, fd
, sock
);
285 active_session (kx_context
*kc
, int fd
, int sock
, int cookiesp
)
287 fd
= connect_local_xsocket(0);
289 if (replace_cookie (fd
, sock
, xauthfile
, cookiesp
))
292 return copy_encrypted (kc
, fd
, sock
);
296 * Handle a new connection.
300 doit_conn (kx_context
*kc
,
301 int fd
, int meta_sock
, int flags
, int cookiesp
)
303 int sock
, sock2
, port
;
304 struct sockaddr_storage __ss_addr
;
305 struct sockaddr
*addr
= (struct sockaddr
*)&__ss_addr
;
306 struct sockaddr_storage __ss_thisaddr
;
307 struct sockaddr
*thisaddr
= (struct sockaddr
*)&__ss_thisaddr
;
309 u_char msg
[1024], *p
;
311 sock
= socket (kc
->thisaddr
->sa_family
, SOCK_STREAM
, 0);
313 syslog (LOG_ERR
, "socket: %m");
316 #if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
319 setsockopt (sock
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&one
, sizeof(one
));
322 #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT)
323 if (flags
& KEEP_ALIVE
) {
326 setsockopt (sock
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&one
,
330 memset (&__ss_addr
, 0, sizeof(__ss_addr
));
331 addr
->sa_family
= kc
->thisaddr
->sa_family
;
332 if (kc
->thisaddr_len
> sizeof(__ss_addr
)) {
333 syslog(LOG_ERR
, "error in af");
336 if (bind (sock
, addr
, kc
->thisaddr_len
) < 0) {
337 syslog (LOG_ERR
, "bind: %m");
340 addrlen
= sizeof(__ss_addr
);
341 if (getsockname (sock
, addr
, &addrlen
) < 0) {
342 syslog (LOG_ERR
, "getsockname: %m");
345 if (listen (sock
, SOMAXCONN
) < 0) {
346 syslog (LOG_ERR
, "listen: %m");
349 port
= socket_get_port(addr
);
353 p
+= kx_put_int (ntohs(port
), p
, 4, 4);
355 if (kx_write (kc
, meta_sock
, msg
, p
- msg
) < 0) {
356 syslog (LOG_ERR
, "write: %m");
360 addrlen
= sizeof(__ss_thisaddr
);
361 sock2
= accept (sock
, thisaddr
, &addrlen
);
363 syslog (LOG_ERR
, "accept: %m");
370 return passive_session (kc
, fd
, sock2
, cookiesp
);
372 return active_session (kc
, fd
, sock2
, cookiesp
);
376 * Is the current user the owner of the console?
380 check_user_console (kx_context
*kc
, int fd
)
384 if (stat ("/dev/console", &sb
) < 0)
385 fatal (kc
, fd
, "Cannot stat /dev/console: %s", strerror(errno
));
386 if (getuid() != sb
.st_uid
)
387 fatal (kc
, fd
, "Permission denied");
390 /* close down the new connection with a reasonable error message */
392 close_connection(int fd
, const char *message
)
394 char buf
[264]; /* max message */
399 mlen
= strlen(message
);
403 /* read first part of connection packet, to get byte order */
404 if(read(fd
, buf
, 6) != 6) {
411 *p
++ = 0; /* failed */
412 *p
++ = mlen
; /* length of message */
413 p
+= 4; /* skip protocol version */
414 p
+= 2; /* skip additional length */
415 memcpy(p
, message
, mlen
); /* copy message */
417 while((p
- buf
) % 4) /* pad to multiple of 4 bytes */
420 /* now fill in length of additional data */
422 buf
[6] = (p
- buf
- 8) / 4;
426 buf
[7] = (p
- buf
- 8) / 4;
428 write(fd
, buf
, p
- buf
);
434 * Handle a passive session on `sock'
438 doit_passive (kx_context
*kc
,
443 struct x_socket
*sockets
,
449 u_char msg
[1024], *p
;
452 display_num
= dispnr
;
454 snprintf (display
, display_size
, "localhost:%u", display_num
);
456 snprintf (display
, display_size
, ":%u", display_num
);
457 error
= create_and_write_cookie (xauthfile
, xauthfile_size
,
460 cleanup(nsockets
, sockets
);
461 fatal (kc
, sock
, "Cookie-creation failed: %s", strerror(error
));
470 len
= strlen (display
);
471 tmp
= kx_put_int (len
, p
, rem
, 4);
472 if (tmp
< 0 || rem
< len
+ 4) {
473 syslog (LOG_ERR
, "doit: buffer too small");
474 cleanup(nsockets
, sockets
);
480 memcpy (p
, display
, len
);
484 len
= strlen (xauthfile
);
485 tmp
= kx_put_int (len
, p
, rem
, 4);
486 if (tmp
< 0 || rem
< len
+ 4) {
487 syslog (LOG_ERR
, "doit: buffer too small");
488 cleanup(nsockets
, sockets
);
494 memcpy (p
, xauthfile
, len
);
498 if(kx_write (kc
, sock
, msg
, p
- msg
) < 0) {
499 syslog (LOG_ERR
, "write: %m");
500 cleanup(nsockets
, sockets
);
512 if (sock
>= FD_SETSIZE
) {
513 syslog (LOG_ERR
, "fd too large");
514 cleanup(nsockets
, sockets
);
519 for (i
= 0; i
< nsockets
; ++i
) {
520 if (sockets
[i
].fd
>= FD_SETSIZE
) {
521 syslog (LOG_ERR
, "fd too large");
522 cleanup(nsockets
, sockets
);
525 FD_SET(sockets
[i
].fd
, &fds
);
527 ret
= select(FD_SETSIZE
, &fds
, NULL
, NULL
, NULL
);
530 if(FD_ISSET(sock
, &fds
)){
531 /* there are no processes left on the remote side
533 cleanup(nsockets
, sockets
);
536 for (i
= 0; i
< nsockets
; ++i
) {
537 if (FD_ISSET(sockets
[i
].fd
, &fds
)) {
538 if (sockets
[i
].flags
== TCP
) {
539 struct sockaddr_storage __ss_peer
;
540 struct sockaddr
*peer
= (struct sockaddr
*)&__ss_peer
;
541 socklen_t slen
= sizeof(__ss_peer
);
543 fd
= accept (sockets
[i
].fd
,
546 if (fd
< 0 && errno
!= EINTR
)
547 syslog (LOG_ERR
, "accept: %m");
550 if (fd
>= 0 && suspicious_address (fd
, peer
)) {
555 } else if(sockets
[i
].flags
== UNIX_SOCKET
) {
558 fd
= accept (sockets
[i
].fd
, NULL
, &zero
);
560 if (fd
< 0 && errno
!= EINTR
)
561 syslog (LOG_ERR
, "accept: %m");
562 #ifdef MAY_HAVE_X11_PIPES
563 } else if(sockets
[i
].flags
== STREAM_PIPE
) {
565 * this code tries to handle the
566 * send fd-over-pipe stuff for
570 struct strrecvfd strrecvfd
;
572 ret
= ioctl (sockets
[i
].fd
,
573 I_RECVFD
, &strrecvfd
);
574 if (ret
< 0 && errno
!= EINTR
) {
575 syslog (LOG_ERR
, "ioctl I_RECVFD: %m");
580 if (strrecvfd
.uid
!= getuid()) {
581 close (strrecvfd
.fd
);
589 #endif /* MAY_HAVE_X11_PIPES */
605 syslog (LOG_ERR
, "fork: %m");
608 close_connection(fd
, strerror(errno
));
609 } else if (child
== 0) {
610 for (i
= 0; i
< nsockets
; ++i
)
611 close (sockets
[i
].fd
);
612 return doit_conn (kc
, fd
, sock
, flags
, cookiesp
);
620 * Handle an active session on `sock'
624 doit_active (kx_context
*kc
,
629 u_char msg
[1024], *p
;
631 check_user_console (kc
, sock
);
636 if(kx_write (kc
, sock
, msg
, p
- msg
) < 0) {
637 syslog (LOG_ERR
, "write: %m");
644 len
= kx_read (kc
, sock
, msg
, sizeof(msg
));
646 syslog (LOG_ERR
, "read: %m");
650 if (*p
!= NEW_CONN
) {
651 syslog (LOG_ERR
, "bad_message: %d", *p
);
657 syslog (LOG_ERR
, "fork: %m");
660 } else if (child
== 0) {
661 return doit_conn (kc
, sock
, sock
, flags
, 1);
668 * Receive a connection on `sock' and process it.
672 doit(int sock
, int tcp_flag
)
678 struct x_socket
*sockets
;
681 flags
= recv_conn (sock
, &context
, &dispnr
, &nsockets
, &sockets
, tcp_flag
);
683 if (flags
& PASSIVE
) {
684 ret
= doit_passive (&context
, sock
, flags
, dispnr
,
685 nsockets
, sockets
, tcp_flag
);
687 ret
= doit_active (&context
, sock
, flags
, tcp_flag
);
688 cleanup(nsockets
, sockets
);
690 context_destroy (&context
);
694 static char *port_str
= NULL
;
695 static int inetd_flag
= 1;
696 static int tcp_flag
= 0;
697 static int version_flag
= 0;
698 static int help_flag
= 0;
700 struct getargs args
[] = {
701 { "inetd", 'i', arg_negative_flag
, &inetd_flag
,
702 "Not started from inetd" },
703 { "tcp", 't', arg_flag
, &tcp_flag
, "Use TCP" },
704 { "port", 'p', arg_string
, &port_str
, "Use this port",
706 { "version", 0, arg_flag
, &version_flag
},
707 { "help", 0, arg_flag
, &help_flag
}
713 arg_printusage (args
,
714 sizeof(args
) / sizeof(args
[0]),
721 * kxd - receive a forwarded X conncection
725 main (int argc
, char **argv
)
730 setprogname (argv
[0]);
731 roken_openlog ("kxd", LOG_ODELAY
| LOG_PID
, LOG_DAEMON
);
733 if (getarg (args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
,
741 print_version (NULL
);
746 struct servent
*s
= roken_getservbyname (port_str
, "tcp");
753 port
= strtol (port_str
, &ptr
, 10);
754 if (port
== 0 && ptr
== port_str
)
755 errx (1, "bad port `%s'", port_str
);
760 port
= krb5_getportbyname(NULL
, "kx", "tcp", KX_PORT
);
762 port
= k_getportbyname ("kx", "tcp", htons(KX_PORT
));
764 #error define KRB4 or KRB5
771 signal (SIGCHLD
, childhandler
);
772 return doit(STDIN_FILENO
, tcp_flag
);