1 /* $OpenBSD: client.c,v 1.151 2021/01/17 16:17:41 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/socket.h> 21 #include <sys/uio.h> 22 #include <sys/un.h> 23 #include <sys/wait.h> 24 25 #include <errno.h> 26 #include <event.h> 27 #include <fcntl.h> 28 #include <imsg.h> 29 #include <signal.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include "tmux.h" 35 36 static struct tmuxproc *client_proc; 37 static struct tmuxpeer *client_peer; 38 static uint64_t client_flags; 39 static int client_suspended; 40 static enum { 41 CLIENT_EXIT_NONE, 42 CLIENT_EXIT_DETACHED, 43 CLIENT_EXIT_DETACHED_HUP, 44 CLIENT_EXIT_LOST_TTY, 45 CLIENT_EXIT_TERMINATED, 46 CLIENT_EXIT_LOST_SERVER, 47 CLIENT_EXIT_EXITED, 48 CLIENT_EXIT_SERVER_EXITED, 49 CLIENT_EXIT_MESSAGE_PROVIDED 50 } client_exitreason = CLIENT_EXIT_NONE; 51 static int client_exitflag; 52 static int client_exitval; 53 static enum msgtype client_exittype; 54 static const char *client_exitsession; 55 static char *client_exitmessage; 56 static const char *client_execshell; 57 static const char *client_execcmd; 58 static int client_attached; 59 static struct client_files client_files = RB_INITIALIZER(&client_files); 60 61 static __dead void client_exec(const char *,const char *); 62 static int client_get_lock(char *); 63 static int client_connect(struct event_base *, const char *, 64 uint64_t); 65 static void client_send_identify(const char *, const char *, int); 66 static void client_signal(int); 67 static void client_dispatch(struct imsg *, void *); 68 static void client_dispatch_attached(struct imsg *); 69 static void client_dispatch_wait(struct imsg *); 70 static const char *client_exit_message(void); 71 72 /* 73 * Get server create lock. If already held then server start is happening in 74 * another client, so block until the lock is released and return -2 to 75 * retry. Return -1 on failure to continue and start the server anyway. 76 */ 77 static int 78 client_get_lock(char *lockfile) 79 { 80 int lockfd; 81 82 log_debug("lock file is %s", lockfile); 83 84 if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) { 85 log_debug("open failed: %s", strerror(errno)); 86 return (-1); 87 } 88 89 if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) { 90 log_debug("flock failed: %s", strerror(errno)); 91 if (errno != EAGAIN) 92 return (lockfd); 93 while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR) 94 /* nothing */; 95 close(lockfd); 96 return (-2); 97 } 98 log_debug("flock succeeded"); 99 100 return (lockfd); 101 } 102 103 /* Connect client to server. */ 104 static int 105 client_connect(struct event_base *base, const char *path, uint64_t flags) 106 { 107 struct sockaddr_un sa; 108 size_t size; 109 int fd, lockfd = -1, locked = 0; 110 char *lockfile = NULL; 111 112 memset(&sa, 0, sizeof sa); 113 sa.sun_family = AF_UNIX; 114 size = strlcpy(sa.sun_path, path, sizeof sa.sun_path); 115 if (size >= sizeof sa.sun_path) { 116 errno = ENAMETOOLONG; 117 return (-1); 118 } 119 log_debug("socket is %s", path); 120 121 retry: 122 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 123 return (-1); 124 125 log_debug("trying connect"); 126 if (connect(fd, (struct sockaddr *)&sa, sizeof sa) == -1) { 127 log_debug("connect failed: %s", strerror(errno)); 128 if (errno != ECONNREFUSED && errno != ENOENT) 129 goto failed; 130 if (flags & CLIENT_NOSTARTSERVER) 131 goto failed; 132 if (~flags & CLIENT_STARTSERVER) 133 goto failed; 134 close(fd); 135 136 if (!locked) { 137 xasprintf(&lockfile, "%s.lock", path); 138 if ((lockfd = client_get_lock(lockfile)) < 0) { 139 log_debug("didn't get lock (%d)", lockfd); 140 141 free(lockfile); 142 lockfile = NULL; 143 144 if (lockfd == -2) 145 goto retry; 146 } 147 log_debug("got lock (%d)", lockfd); 148 149 /* 150 * Always retry at least once, even if we got the lock, 151 * because another client could have taken the lock, 152 * started the server and released the lock between our 153 * connect() and flock(). 154 */ 155 locked = 1; 156 goto retry; 157 } 158 159 if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) { 160 free(lockfile); 161 close(lockfd); 162 return (-1); 163 } 164 fd = server_start(client_proc, flags, base, lockfd, lockfile); 165 } 166 167 if (locked && lockfd >= 0) { 168 free(lockfile); 169 close(lockfd); 170 } 171 setblocking(fd, 0); 172 return (fd); 173 174 failed: 175 if (locked) { 176 free(lockfile); 177 close(lockfd); 178 } 179 close(fd); 180 return (-1); 181 } 182 183 /* Get exit string from reason number. */ 184 const char * 185 client_exit_message(void) 186 { 187 static char msg[256]; 188 189 switch (client_exitreason) { 190 case CLIENT_EXIT_NONE: 191 break; 192 case CLIENT_EXIT_DETACHED: 193 if (client_exitsession != NULL) { 194 xsnprintf(msg, sizeof msg, "detached " 195 "(from session %s)", client_exitsession); 196 return (msg); 197 } 198 return ("detached"); 199 case CLIENT_EXIT_DETACHED_HUP: 200 if (client_exitsession != NULL) { 201 xsnprintf(msg, sizeof msg, "detached and SIGHUP " 202 "(from session %s)", client_exitsession); 203 return (msg); 204 } 205 return ("detached and SIGHUP"); 206 case CLIENT_EXIT_LOST_TTY: 207 return ("lost tty"); 208 case CLIENT_EXIT_TERMINATED: 209 return ("terminated"); 210 case CLIENT_EXIT_LOST_SERVER: 211 return ("server exited unexpectedly"); 212 case CLIENT_EXIT_EXITED: 213 return ("exited"); 214 case CLIENT_EXIT_SERVER_EXITED: 215 return ("server exited"); 216 case CLIENT_EXIT_MESSAGE_PROVIDED: 217 return (client_exitmessage); 218 } 219 return ("unknown reason"); 220 } 221 222 /* Exit if all streams flushed. */ 223 static void 224 client_exit(void) 225 { 226 struct client_file *cf; 227 size_t left; 228 int waiting = 0; 229 230 RB_FOREACH (cf, client_files, &client_files) { 231 if (cf->event == NULL) 232 continue; 233 left = EVBUFFER_LENGTH(cf->event->output); 234 if (left != 0) { 235 waiting++; 236 log_debug("file %u %zu bytes left", cf->stream, left); 237 } 238 } 239 if (waiting == 0) 240 proc_exit(client_proc); 241 } 242 243 /* Client main loop. */ 244 int 245 client_main(struct event_base *base, int argc, char **argv, uint64_t flags, 246 int feat) 247 { 248 struct cmd_parse_result *pr; 249 struct msg_command *data; 250 int fd, i; 251 const char *ttynam, *cwd; 252 pid_t ppid; 253 enum msgtype msg; 254 struct termios tio, saved_tio; 255 size_t size, linesize = 0; 256 ssize_t linelen; 257 char *line = NULL; 258 259 /* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */ 260 signal(SIGCHLD, SIG_IGN); 261 262 /* Set up the initial command. */ 263 if (shell_command != NULL) { 264 msg = MSG_SHELL; 265 flags |= CLIENT_STARTSERVER; 266 } else if (argc == 0) { 267 msg = MSG_COMMAND; 268 flags |= CLIENT_STARTSERVER; 269 } else { 270 msg = MSG_COMMAND; 271 272 /* 273 * It sucks parsing the command string twice (in client and 274 * later in server) but it is necessary to get the start server 275 * flag. 276 */ 277 pr = cmd_parse_from_arguments(argc, argv, NULL); 278 if (pr->status == CMD_PARSE_SUCCESS) { 279 if (cmd_list_any_have(pr->cmdlist, CMD_STARTSERVER)) 280 flags |= CLIENT_STARTSERVER; 281 cmd_list_free(pr->cmdlist); 282 } else 283 free(pr->error); 284 } 285 286 /* Create client process structure (starts logging). */ 287 client_proc = proc_start("client"); 288 proc_set_signals(client_proc, client_signal); 289 290 /* Save the flags. */ 291 client_flags = flags; 292 log_debug("flags are %#llx", (unsigned long long)client_flags); 293 294 /* Initialize the client socket and start the server. */ 295 fd = client_connect(base, socket_path, client_flags); 296 if (fd == -1) { 297 if (errno == ECONNREFUSED) { 298 fprintf(stderr, "no server running on %s\n", 299 socket_path); 300 } else { 301 fprintf(stderr, "error connecting to %s (%s)\n", 302 socket_path, strerror(errno)); 303 } 304 return (1); 305 } 306 client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL); 307 308 /* Save these before pledge(). */ 309 if ((cwd = find_cwd()) == NULL && (cwd = find_home()) == NULL) 310 cwd = "/"; 311 if ((ttynam = ttyname(STDIN_FILENO)) == NULL) 312 ttynam = ""; 313 314 /* 315 * Drop privileges for client. "proc exec" is needed for -c and for 316 * locking (which uses system(3)). 317 * 318 * "tty" is needed to restore termios(4) and also for some reason -CC 319 * does not work properly without it (input is not recognised). 320 * 321 * "sendfd" is dropped later in client_dispatch_wait(). 322 */ 323 if (pledge( 324 "stdio rpath wpath cpath unix sendfd proc exec tty", 325 NULL) != 0) 326 fatal("pledge failed"); 327 328 /* Free stuff that is not used in the client. */ 329 if (ptm_fd != -1) 330 close(ptm_fd); 331 options_free(global_options); 332 options_free(global_s_options); 333 options_free(global_w_options); 334 environ_free(global_environ); 335 336 /* Set up control mode. */ 337 if (client_flags & CLIENT_CONTROLCONTROL) { 338 if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) { 339 fprintf(stderr, "tcgetattr failed: %s\n", 340 strerror(errno)); 341 return (1); 342 } 343 cfmakeraw(&tio); 344 tio.c_iflag = ICRNL|IXANY; 345 tio.c_oflag = OPOST|ONLCR; 346 tio.c_lflag = NOKERNINFO; 347 tio.c_cflag = CREAD|CS8|HUPCL; 348 tio.c_cc[VMIN] = 1; 349 tio.c_cc[VTIME] = 0; 350 cfsetispeed(&tio, cfgetispeed(&saved_tio)); 351 cfsetospeed(&tio, cfgetospeed(&saved_tio)); 352 tcsetattr(STDIN_FILENO, TCSANOW, &tio); 353 } 354 355 /* Send identify messages. */ 356 client_send_identify(ttynam, cwd, feat); 357 358 /* Send first command. */ 359 if (msg == MSG_COMMAND) { 360 /* How big is the command? */ 361 size = 0; 362 for (i = 0; i < argc; i++) 363 size += strlen(argv[i]) + 1; 364 if (size > MAX_IMSGSIZE - (sizeof *data)) { 365 fprintf(stderr, "command too long\n"); 366 return (1); 367 } 368 data = xmalloc((sizeof *data) + size); 369 370 /* Prepare command for server. */ 371 data->argc = argc; 372 if (cmd_pack_argv(argc, argv, (char *)(data + 1), size) != 0) { 373 fprintf(stderr, "command too long\n"); 374 free(data); 375 return (1); 376 } 377 size += sizeof *data; 378 379 /* Send the command. */ 380 if (proc_send(client_peer, msg, -1, data, size) != 0) { 381 fprintf(stderr, "failed to send command\n"); 382 free(data); 383 return (1); 384 } 385 free(data); 386 } else if (msg == MSG_SHELL) 387 proc_send(client_peer, msg, -1, NULL, 0); 388 389 /* Start main loop. */ 390 proc_loop(client_proc, NULL); 391 392 /* Run command if user requested exec, instead of exiting. */ 393 if (client_exittype == MSG_EXEC) { 394 if (client_flags & CLIENT_CONTROLCONTROL) 395 tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio); 396 client_exec(client_execshell, client_execcmd); 397 } 398 399 /* Restore streams to blocking. */ 400 setblocking(STDIN_FILENO, 1); 401 setblocking(STDOUT_FILENO, 1); 402 setblocking(STDERR_FILENO, 1); 403 404 /* Print the exit message, if any, and exit. */ 405 if (client_attached) { 406 if (client_exitreason != CLIENT_EXIT_NONE) 407 printf("[%s]\n", client_exit_message()); 408 409 ppid = getppid(); 410 if (client_exittype == MSG_DETACHKILL && ppid > 1) 411 kill(ppid, SIGHUP); 412 } else if (client_flags & CLIENT_CONTROL) { 413 if (client_exitreason != CLIENT_EXIT_NONE) 414 printf("%%exit %s\n", client_exit_message()); 415 else 416 printf("%%exit\n"); 417 fflush(stdout); 418 if (client_flags & CLIENT_CONTROL_WAITEXIT) { 419 setvbuf(stdin, NULL, _IOLBF, 0); 420 for (;;) { 421 linelen = getline(&line, &linesize, stdin); 422 if (linelen <= 1) 423 break; 424 } 425 free(line); 426 } 427 if (client_flags & CLIENT_CONTROLCONTROL) { 428 printf("\033\\"); 429 fflush(stdout); 430 tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio); 431 } 432 } else if (client_exitreason != CLIENT_EXIT_NONE) 433 fprintf(stderr, "%s\n", client_exit_message()); 434 return (client_exitval); 435 } 436 437 /* Send identify messages to server. */ 438 static void 439 client_send_identify(const char *ttynam, const char *cwd, int feat) 440 { 441 const char *s; 442 char **ss; 443 size_t sslen; 444 int fd, flags = client_flags; 445 pid_t pid; 446 447 proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags); 448 proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags, 449 sizeof client_flags); 450 451 if ((s = getenv("TERM")) == NULL) 452 s = ""; 453 proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1); 454 proc_send(client_peer, MSG_IDENTIFY_FEATURES, -1, &feat, sizeof feat); 455 456 proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam, 457 strlen(ttynam) + 1); 458 proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1); 459 460 if ((fd = dup(STDIN_FILENO)) == -1) 461 fatal("dup failed"); 462 proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0); 463 if ((fd = dup(STDOUT_FILENO)) == -1) 464 fatal("dup failed"); 465 proc_send(client_peer, MSG_IDENTIFY_STDOUT, fd, NULL, 0); 466 467 pid = getpid(); 468 proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid); 469 470 for (ss = environ; *ss != NULL; ss++) { 471 sslen = strlen(*ss) + 1; 472 if (sslen > MAX_IMSGSIZE - IMSG_HEADER_SIZE) 473 continue; 474 proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen); 475 } 476 477 proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0); 478 } 479 480 /* File write error callback. */ 481 static void 482 client_write_error_callback(__unused struct bufferevent *bev, 483 __unused short what, void *arg) 484 { 485 struct client_file *cf = arg; 486 487 log_debug("write error file %d", cf->stream); 488 489 bufferevent_free(cf->event); 490 cf->event = NULL; 491 492 close(cf->fd); 493 cf->fd = -1; 494 495 if (client_exitflag) 496 client_exit(); 497 } 498 499 /* File write callback. */ 500 static void 501 client_write_callback(__unused struct bufferevent *bev, void *arg) 502 { 503 struct client_file *cf = arg; 504 505 if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0) { 506 bufferevent_free(cf->event); 507 close(cf->fd); 508 RB_REMOVE(client_files, &client_files, cf); 509 file_free(cf); 510 } 511 512 if (client_exitflag) 513 client_exit(); 514 } 515 516 /* Open write file. */ 517 static void 518 client_write_open(void *data, size_t datalen) 519 { 520 struct msg_write_open *msg = data; 521 const char *path; 522 struct msg_write_ready reply; 523 struct client_file find, *cf; 524 const int flags = O_NONBLOCK|O_WRONLY|O_CREAT; 525 int error = 0; 526 527 if (datalen < sizeof *msg) 528 fatalx("bad MSG_WRITE_OPEN size"); 529 if (datalen == sizeof *msg) 530 path = "-"; 531 else 532 path = (const char *)(msg + 1); 533 log_debug("open write file %d %s", msg->stream, path); 534 535 find.stream = msg->stream; 536 if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) { 537 cf = file_create(NULL, msg->stream, NULL, NULL); 538 RB_INSERT(client_files, &client_files, cf); 539 } else { 540 error = EBADF; 541 goto reply; 542 } 543 if (cf->closed) { 544 error = EBADF; 545 goto reply; 546 } 547 548 cf->fd = -1; 549 if (msg->fd == -1) 550 cf->fd = open(path, msg->flags|flags, 0644); 551 else { 552 if (msg->fd != STDOUT_FILENO && msg->fd != STDERR_FILENO) 553 errno = EBADF; 554 else { 555 cf->fd = dup(msg->fd); 556 if (~client_flags & CLIENT_CONTROL) 557 close(msg->fd); /* can only be used once */ 558 } 559 } 560 if (cf->fd == -1) { 561 error = errno; 562 goto reply; 563 } 564 565 cf->event = bufferevent_new(cf->fd, NULL, client_write_callback, 566 client_write_error_callback, cf); 567 bufferevent_enable(cf->event, EV_WRITE); 568 goto reply; 569 570 reply: 571 reply.stream = msg->stream; 572 reply.error = error; 573 proc_send(client_peer, MSG_WRITE_READY, -1, &reply, sizeof reply); 574 } 575 576 /* Write to client file. */ 577 static void 578 client_write_data(void *data, size_t datalen) 579 { 580 struct msg_write_data *msg = data; 581 struct client_file find, *cf; 582 size_t size = datalen - sizeof *msg; 583 584 if (datalen < sizeof *msg) 585 fatalx("bad MSG_WRITE size"); 586 find.stream = msg->stream; 587 if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) 588 fatalx("unknown stream number"); 589 log_debug("write %zu to file %d", size, cf->stream); 590 591 if (cf->event != NULL) 592 bufferevent_write(cf->event, msg + 1, size); 593 } 594 595 /* Close client file. */ 596 static void 597 client_write_close(void *data, size_t datalen) 598 { 599 struct msg_write_close *msg = data; 600 struct client_file find, *cf; 601 602 if (datalen != sizeof *msg) 603 fatalx("bad MSG_WRITE_CLOSE size"); 604 find.stream = msg->stream; 605 if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) 606 fatalx("unknown stream number"); 607 log_debug("close file %d", cf->stream); 608 609 if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) { 610 if (cf->event != NULL) 611 bufferevent_free(cf->event); 612 if (cf->fd != -1) 613 close(cf->fd); 614 RB_REMOVE(client_files, &client_files, cf); 615 file_free(cf); 616 } 617 } 618 619 /* File read callback. */ 620 static void 621 client_read_callback(__unused struct bufferevent *bev, void *arg) 622 { 623 struct client_file *cf = arg; 624 void *bdata; 625 size_t bsize; 626 struct msg_read_data *msg; 627 size_t msglen; 628 629 msg = xmalloc(sizeof *msg); 630 for (;;) { 631 bdata = EVBUFFER_DATA(cf->event->input); 632 bsize = EVBUFFER_LENGTH(cf->event->input); 633 634 if (bsize == 0) 635 break; 636 if (bsize > MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg) 637 bsize = MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg; 638 log_debug("read %zu from file %d", bsize, cf->stream); 639 640 msglen = (sizeof *msg) + bsize; 641 msg = xrealloc(msg, msglen); 642 msg->stream = cf->stream; 643 memcpy(msg + 1, bdata, bsize); 644 proc_send(client_peer, MSG_READ, -1, msg, msglen); 645 646 evbuffer_drain(cf->event->input, bsize); 647 } 648 free(msg); 649 } 650 651 /* File read error callback. */ 652 static void 653 client_read_error_callback(__unused struct bufferevent *bev, 654 __unused short what, void *arg) 655 { 656 struct client_file *cf = arg; 657 struct msg_read_done msg; 658 659 log_debug("read error file %d", cf->stream); 660 661 msg.stream = cf->stream; 662 msg.error = 0; 663 proc_send(client_peer, MSG_READ_DONE, -1, &msg, sizeof msg); 664 665 bufferevent_free(cf->event); 666 close(cf->fd); 667 RB_REMOVE(client_files, &client_files, cf); 668 file_free(cf); 669 } 670 671 /* Open read file. */ 672 static void 673 client_read_open(void *data, size_t datalen) 674 { 675 struct msg_read_open *msg = data; 676 const char *path; 677 struct msg_read_done reply; 678 struct client_file find, *cf; 679 const int flags = O_NONBLOCK|O_RDONLY; 680 int error; 681 682 if (datalen < sizeof *msg) 683 fatalx("bad MSG_READ_OPEN size"); 684 if (datalen == sizeof *msg) 685 path = "-"; 686 else 687 path = (const char *)(msg + 1); 688 log_debug("open read file %d %s", msg->stream, path); 689 690 find.stream = msg->stream; 691 if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) { 692 cf = file_create(NULL, msg->stream, NULL, NULL); 693 RB_INSERT(client_files, &client_files, cf); 694 } else { 695 error = EBADF; 696 goto reply; 697 } 698 if (cf->closed) { 699 error = EBADF; 700 goto reply; 701 } 702 703 cf->fd = -1; 704 if (msg->fd == -1) 705 cf->fd = open(path, flags); 706 else { 707 if (msg->fd != STDIN_FILENO) 708 errno = EBADF; 709 else { 710 cf->fd = dup(msg->fd); 711 if (~client_flags & CLIENT_CONTROL) 712 close(msg->fd); /* can only be used once */ 713 } 714 } 715 if (cf->fd == -1) { 716 error = errno; 717 goto reply; 718 } 719 720 cf->event = bufferevent_new(cf->fd, client_read_callback, NULL, 721 client_read_error_callback, cf); 722 bufferevent_enable(cf->event, EV_READ); 723 return; 724 725 reply: 726 reply.stream = msg->stream; 727 reply.error = error; 728 proc_send(client_peer, MSG_READ_DONE, -1, &reply, sizeof reply); 729 } 730 731 /* Run command in shell; used for -c. */ 732 static __dead void 733 client_exec(const char *shell, const char *shellcmd) 734 { 735 const char *name, *ptr; 736 char *argv0; 737 738 log_debug("shell %s, command %s", shell, shellcmd); 739 740 ptr = strrchr(shell, '/'); 741 if (ptr != NULL && *(ptr + 1) != '\0') 742 name = ptr + 1; 743 else 744 name = shell; 745 if (client_flags & CLIENT_LOGIN) 746 xasprintf(&argv0, "-%s", name); 747 else 748 xasprintf(&argv0, "%s", name); 749 setenv("SHELL", shell, 1); 750 751 proc_clear_signals(client_proc, 1); 752 753 setblocking(STDIN_FILENO, 1); 754 setblocking(STDOUT_FILENO, 1); 755 setblocking(STDERR_FILENO, 1); 756 closefrom(STDERR_FILENO + 1); 757 758 execl(shell, argv0, "-c", shellcmd, (char *) NULL); 759 fatal("execl failed"); 760 } 761 762 /* Callback to handle signals in the client. */ 763 static void 764 client_signal(int sig) 765 { 766 struct sigaction sigact; 767 int status; 768 769 log_debug("%s: %s", __func__, strsignal(sig)); 770 if (sig == SIGCHLD) 771 waitpid(WAIT_ANY, &status, WNOHANG); 772 else if (!client_attached) { 773 if (sig == SIGTERM) 774 proc_exit(client_proc); 775 } else { 776 switch (sig) { 777 case SIGHUP: 778 client_exitreason = CLIENT_EXIT_LOST_TTY; 779 client_exitval = 1; 780 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 781 break; 782 case SIGTERM: 783 if (!client_suspended) 784 client_exitreason = CLIENT_EXIT_TERMINATED; 785 client_exitval = 1; 786 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 787 break; 788 case SIGWINCH: 789 proc_send(client_peer, MSG_RESIZE, -1, NULL, 0); 790 break; 791 case SIGCONT: 792 memset(&sigact, 0, sizeof sigact); 793 sigemptyset(&sigact.sa_mask); 794 sigact.sa_flags = SA_RESTART; 795 sigact.sa_handler = SIG_IGN; 796 if (sigaction(SIGTSTP, &sigact, NULL) != 0) 797 fatal("sigaction failed"); 798 proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0); 799 client_suspended = 0; 800 break; 801 } 802 } 803 } 804 805 /* Callback for client read events. */ 806 static void 807 client_dispatch(struct imsg *imsg, __unused void *arg) 808 { 809 if (imsg == NULL) { 810 client_exitreason = CLIENT_EXIT_LOST_SERVER; 811 client_exitval = 1; 812 proc_exit(client_proc); 813 return; 814 } 815 816 if (client_attached) 817 client_dispatch_attached(imsg); 818 else 819 client_dispatch_wait(imsg); 820 } 821 822 /* Process an exit message. */ 823 static void 824 client_dispatch_exit_message(char *data, size_t datalen) 825 { 826 int retval; 827 828 if (datalen < sizeof retval && datalen != 0) 829 fatalx("bad MSG_EXIT size"); 830 831 if (datalen >= sizeof retval) { 832 memcpy(&retval, data, sizeof retval); 833 client_exitval = retval; 834 } 835 836 if (datalen > sizeof retval) { 837 datalen -= sizeof retval; 838 data += sizeof retval; 839 840 client_exitmessage = xmalloc(datalen); 841 memcpy(client_exitmessage, data, datalen); 842 client_exitmessage[datalen - 1] = '\0'; 843 844 client_exitreason = CLIENT_EXIT_MESSAGE_PROVIDED; 845 } 846 } 847 848 /* Dispatch imsgs when in wait state (before MSG_READY). */ 849 static void 850 client_dispatch_wait(struct imsg *imsg) 851 { 852 char *data; 853 ssize_t datalen; 854 static int pledge_applied; 855 856 /* 857 * "sendfd" is no longer required once all of the identify messages 858 * have been sent. We know the server won't send us anything until that 859 * point (because we don't ask it to), so we can drop "sendfd" once we 860 * get the first message from the server. 861 */ 862 if (!pledge_applied) { 863 if (pledge( 864 "stdio rpath wpath cpath unix proc exec tty", 865 NULL) != 0) 866 fatal("pledge failed"); 867 pledge_applied = 1; 868 } 869 870 data = imsg->data; 871 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 872 873 switch (imsg->hdr.type) { 874 case MSG_EXIT: 875 case MSG_SHUTDOWN: 876 client_dispatch_exit_message(data, datalen); 877 client_exitflag = 1; 878 client_exit(); 879 break; 880 case MSG_READY: 881 if (datalen != 0) 882 fatalx("bad MSG_READY size"); 883 884 client_attached = 1; 885 proc_send(client_peer, MSG_RESIZE, -1, NULL, 0); 886 break; 887 case MSG_VERSION: 888 if (datalen != 0) 889 fatalx("bad MSG_VERSION size"); 890 891 fprintf(stderr, "protocol version mismatch " 892 "(client %d, server %u)\n", PROTOCOL_VERSION, 893 imsg->hdr.peerid & 0xff); 894 client_exitval = 1; 895 proc_exit(client_proc); 896 break; 897 case MSG_FLAGS: 898 if (datalen != sizeof client_flags) 899 fatalx("bad MSG_FLAGS string"); 900 901 memcpy(&client_flags, data, sizeof client_flags); 902 log_debug("new flags are %#llx", 903 (unsigned long long)client_flags); 904 break; 905 case MSG_SHELL: 906 if (datalen == 0 || data[datalen - 1] != '\0') 907 fatalx("bad MSG_SHELL string"); 908 909 client_exec(data, shell_command); 910 /* NOTREACHED */ 911 case MSG_DETACH: 912 case MSG_DETACHKILL: 913 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 914 break; 915 case MSG_EXITED: 916 proc_exit(client_proc); 917 break; 918 case MSG_READ_OPEN: 919 client_read_open(data, datalen); 920 break; 921 case MSG_WRITE_OPEN: 922 client_write_open(data, datalen); 923 break; 924 case MSG_WRITE: 925 client_write_data(data, datalen); 926 break; 927 case MSG_WRITE_CLOSE: 928 client_write_close(data, datalen); 929 break; 930 case MSG_OLDSTDERR: 931 case MSG_OLDSTDIN: 932 case MSG_OLDSTDOUT: 933 fprintf(stderr, "server version is too old for client\n"); 934 proc_exit(client_proc); 935 break; 936 } 937 } 938 939 /* Dispatch imsgs in attached state (after MSG_READY). */ 940 static void 941 client_dispatch_attached(struct imsg *imsg) 942 { 943 struct sigaction sigact; 944 char *data; 945 ssize_t datalen; 946 947 data = imsg->data; 948 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 949 950 switch (imsg->hdr.type) { 951 case MSG_FLAGS: 952 if (datalen != sizeof client_flags) 953 fatalx("bad MSG_FLAGS string"); 954 955 memcpy(&client_flags, data, sizeof client_flags); 956 log_debug("new flags are %#llx", 957 (unsigned long long)client_flags); 958 break; 959 case MSG_DETACH: 960 case MSG_DETACHKILL: 961 if (datalen == 0 || data[datalen - 1] != '\0') 962 fatalx("bad MSG_DETACH string"); 963 964 client_exitsession = xstrdup(data); 965 client_exittype = imsg->hdr.type; 966 if (imsg->hdr.type == MSG_DETACHKILL) 967 client_exitreason = CLIENT_EXIT_DETACHED_HUP; 968 else 969 client_exitreason = CLIENT_EXIT_DETACHED; 970 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 971 break; 972 case MSG_EXEC: 973 if (datalen == 0 || data[datalen - 1] != '\0' || 974 strlen(data) + 1 == (size_t)datalen) 975 fatalx("bad MSG_EXEC string"); 976 client_execcmd = xstrdup(data); 977 client_execshell = xstrdup(data + strlen(data) + 1); 978 979 client_exittype = imsg->hdr.type; 980 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 981 break; 982 case MSG_EXIT: 983 client_dispatch_exit_message(data, datalen); 984 if (client_exitreason == CLIENT_EXIT_NONE) 985 client_exitreason = CLIENT_EXIT_EXITED; 986 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 987 break; 988 case MSG_EXITED: 989 if (datalen != 0) 990 fatalx("bad MSG_EXITED size"); 991 992 proc_exit(client_proc); 993 break; 994 case MSG_SHUTDOWN: 995 if (datalen != 0) 996 fatalx("bad MSG_SHUTDOWN size"); 997 998 proc_send(client_peer, MSG_EXITING, -1, NULL, 0); 999 client_exitreason = CLIENT_EXIT_SERVER_EXITED; 1000 client_exitval = 1; 1001 break; 1002 case MSG_SUSPEND: 1003 if (datalen != 0) 1004 fatalx("bad MSG_SUSPEND size"); 1005 1006 memset(&sigact, 0, sizeof sigact); 1007 sigemptyset(&sigact.sa_mask); 1008 sigact.sa_flags = SA_RESTART; 1009 sigact.sa_handler = SIG_DFL; 1010 if (sigaction(SIGTSTP, &sigact, NULL) != 0) 1011 fatal("sigaction failed"); 1012 client_suspended = 1; 1013 kill(getpid(), SIGTSTP); 1014 break; 1015 case MSG_LOCK: 1016 if (datalen == 0 || data[datalen - 1] != '\0') 1017 fatalx("bad MSG_LOCK string"); 1018 1019 system(data); 1020 proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0); 1021 break; 1022 } 1023 } 1024