… | |
… | |
29 | |
29 | |
30 | #include "ptytty.h" |
30 | #include "ptytty.h" |
31 | |
31 | |
32 | #include <cstdlib> |
32 | #include <cstdlib> |
33 | #include <cstring> |
33 | #include <cstring> |
|
|
34 | #include <csignal> |
34 | |
35 | |
35 | #include <sys/types.h> |
36 | #include <sys/types.h> |
36 | #include <sys/socket.h> |
37 | #include <sys/socket.h> |
37 | #include <unistd.h> |
38 | #include <unistd.h> |
38 | #include <fcntl.h> |
39 | #include <fcntl.h> |
… | |
… | |
371 | } |
372 | } |
372 | |
373 | |
373 | return true; |
374 | return true; |
374 | } |
375 | } |
375 | |
376 | |
|
|
377 | ///////////////////////////////////////////////////////////////////////////// |
|
|
378 | // helper/proxy support |
|
|
379 | |
376 | #if PTYTTY_HELPER |
380 | #if PTYTTY_HELPER |
377 | |
381 | |
378 | static int sock_fd = -1; |
382 | static int sock_fd = -1, lock_fd = -1; |
379 | static int helper_pid, owner_pid; |
383 | static int helper_pid, owner_pid; |
380 | |
384 | |
381 | struct command |
385 | struct command |
382 | { |
386 | { |
383 | enum { get, login, destroy } type; |
387 | enum { get, login, destroy } type; |
… | |
… | |
523 | int sv[2]; |
527 | int sv[2]; |
524 | |
528 | |
525 | if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv)) |
529 | if (socketpair (AF_UNIX, SOCK_STREAM, 0, sv)) |
526 | ptytty_fatal ("could not create socket to communicate with pty/sessiondb helper, aborting.\n"); |
530 | ptytty_fatal ("could not create socket to communicate with pty/sessiondb helper, aborting.\n"); |
527 | |
531 | |
|
|
532 | #ifdef PTYTTY_REENTRANT |
|
|
533 | int lv[2]; |
|
|
534 | |
|
|
535 | if (socketpair (AF_UNIX, SOCK_STREAM, 0, lv)) |
|
|
536 | ptytty_fatal ("could not create socket to communicate with pty/sessiondb helper, aborting.\n"); |
|
|
537 | #endif |
|
|
538 | |
528 | helper_pid = fork (); |
539 | helper_pid = fork (); |
529 | |
540 | |
530 | if (helper_pid < 0) |
541 | if (helper_pid < 0) |
531 | ptytty_fatal ("could not create pty/sessiondb helper process, aborting.\n"); |
542 | ptytty_fatal ("could not create pty/sessiondb helper process, aborting.\n"); |
532 | |
543 | |
… | |
… | |
534 | { |
545 | { |
535 | // client, process |
546 | // client, process |
536 | sock_fd = sv[0]; |
547 | sock_fd = sv[0]; |
537 | close (sv[1]); |
548 | close (sv[1]); |
538 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
549 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
|
|
550 | #ifdef PTYTTY_REENTRANT |
|
|
551 | lock_fd = lv[0]; |
|
|
552 | close (lv[1]); |
|
|
553 | fcntl (lock_fd, F_SETFD, FD_CLOEXEC); |
|
|
554 | #endif |
539 | } |
555 | } |
540 | else |
556 | else |
541 | { |
557 | { |
542 | // server, pty-helper |
558 | // server, pty-helper |
543 | sock_fd = sv[1]; |
559 | sock_fd = sv[1]; |
|
|
560 | #ifdef PTYTTY_REENTRANT |
|
|
561 | lock_fd = lv[1]; |
|
|
562 | #endif |
544 | |
563 | |
545 | chdir ("/"); |
564 | chdir ("/"); |
546 | |
565 | |
|
|
566 | signal (SIGHUP, SIG_IGN); |
|
|
567 | signal (SIGTERM, SIG_IGN); |
|
|
568 | signal (SIGINT, SIG_IGN); |
|
|
569 | signal (SIGPIPE, SIG_IGN); |
|
|
570 | |
547 | for (int fd = 0; fd < 1023; fd++) |
571 | for (int fd = 0; fd < 1023; fd++) |
548 | if (fd != sock_fd) |
572 | if (fd != sock_fd && fd != lock_fd) |
549 | close (fd); |
573 | close (fd); |
550 | |
574 | |
551 | serve (); |
575 | serve (); |
552 | _exit (EXIT_SUCCESS); |
576 | _exit (EXIT_SUCCESS); |
553 | } |
577 | } |
… | |
… | |
609 | if (uid != geteuid () |
633 | if (uid != geteuid () |
610 | || gid != getegid ()) |
634 | || gid != getegid ()) |
611 | ptytty_fatal ("unable to drop privileges, aborting.\n"); |
635 | ptytty_fatal ("unable to drop privileges, aborting.\n"); |
612 | } |
636 | } |
613 | |
637 | |
|
|
638 | ///////////////////////////////////////////////////////////////////////////// |
|
|
639 | // C API |
|
|
640 | |
|
|
641 | #ifndef NO_C_API |
|
|
642 | |
|
|
643 | #define DEFINE_METHOD(retval, name, args1, args2) \ |
|
|
644 | extern "C" retval ptytty_ ## name args1 \ |
|
|
645 | { return ((struct ptytty *)ptytty)->name args2; } |
|
|
646 | |
|
|
647 | DEFINE_METHOD(int,pty,(void *ptytty),) |
|
|
648 | DEFINE_METHOD(int,tty,(void *ptytty),) |
|
|
649 | DEFINE_METHOD(int,get,(void *ptytty),()) |
|
|
650 | DEFINE_METHOD(void,login,(void *ptytty, int cmd_pid, bool login_shell, const char *hostname),(cmd_pid,login_shell,hostname)) |
|
|
651 | |
|
|
652 | DEFINE_METHOD(void,close_tty,(void *ptytty),()) |
|
|
653 | DEFINE_METHOD(int,make_controlling_tty,(void *ptytty),()) |
|
|
654 | DEFINE_METHOD(void,set_utf8_mode,(void *ptytty, int on),(on)) |
|
|
655 | |
|
|
656 | #define DEFINE_STATIC(retval, name, args) \ |
|
|
657 | extern "C" retval ptytty_ ## name args \ |
|
|
658 | { return ptytty::name args; } |
|
|
659 | |
|
|
660 | DEFINE_STATIC(void,drop_privileges,()) |
|
|
661 | DEFINE_STATIC(void,use_helper,()) |
|
|
662 | DEFINE_STATIC(void,init,()) |
|
|
663 | |
|
|
664 | DEFINE_STATIC(void *,create,()) |
|
|
665 | |
|
|
666 | void ptytty_delete (void *ptytty) |
|
|
667 | { |
|
|
668 | delete (struct ptytty *)ptytty; |
|
|
669 | } |
|
|
670 | |
|
|
671 | // send_fd, recv_fd not exposed |
|
|
672 | |
|
|
673 | #endif |