我在shell的shell中实现了挂钩和记录输入的命令。它由libhook(用于挂钩的库)和带有“Unix 98 pty”的脚本(由此脚本实现http://honeypots.sourceforge.net/script.c.solaris.txt制作)发布。
如果我在登录的ssh会话中从shell启动“脚本”,一切运行良好并且有一些命令输出ps。但是如果脚本是由libhook启动的(在登录ssh时,libhooks检测到有SHELL的调用并启动脚本而不是SHELL)命令ps有下一个输出:
ps: no controlling terminal
如果挂钩登录会话(在“脚本”下)有pid = 19215,在这种情况下在干净(未挂钩)ssh会话下“ps -el”显示下一个:
# ps -el
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
1 T 0 0 0 0 0 SY ? 0 ? 0:20 sched
0 S 0 1 0 0 40 20 ? 385 ? ? 0:04 init
1 S 0 2 0 0 0 SY ? 0 ? ? 0:00 pageout
1 S 0 3 0 0 0 SY ? 0 ? ? 142:52 fsflush
1 S 0 4 0 0 0 SD ? 0 ? ? 0:57 vmtasks
......
0 S 0 19215 19211 0 40 20 ? 506 ? pts/6 0:00 sh
0 S 0 19211 19205 0 40 20 ? 881 ? pts/5 0:00 script
0 S 0 19205 19204 0 40 20 ? 1244 ? ? 0:01 sshd
0 S 0 19204 19203 0 40 20 ? 746 ? ? 0:00 sshd
0 S 0 19203 1 0 40 20 ? 603 ? ? 0:00 sshd
......
“脚本”的结构调用下一个:
struct termios origtty, newtty;
tcgetattr(STDIN_FILENO, &origtty); // get tty modes
int master = open("/dev/ptmx", O_RDWR)); // opens master side of pseudo-tty
grantpt(master); // set the permissions on the slave
unlockpt(master); // unlock the slave.
pid = fork(); // create child for slave
然后在子进程中有下一个调用:
setsid(); // creates new process session
char * slavename = ptsname(master); // get slave name
int slave = open(slaveName, O_RDWR) // open the slave pseudo-tty
ioctl(slave, I_PUSH, "ptem"); // push the hardware emulation module
ioctl(slave, I_PUSH, "ldterm"); // push the line discipline module
tcsetattr(slave, TCSANOW, & ttymodes); // copy the user's terminal modes to the slave pseudo-tty
close(master); // close the the master; this are not needed in the slave.
dup2(slave, 0);
dup2(slave, 1);
dup2(slave, 2);
close(slave); // set the slave to be our standard input, output, and error output.
execl("/sbin/sh", "sh", NULL); // run shell there
父进程的有下一个调用:
newtty = origtty;
newtty.c_cc[VMIN] = 1;
newtty.c_cc[VTIME] = 0;
newtty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
newtty.c_oflag &= ~OPOST;
newtty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
newtty.c_cflag &= ~(CSIZE | PARENB);
newtty.c_cflag |= CS8;
我试图在命令“setsid”之前获得“controlTerm = open(”/ dev / tty“,O_RDWR)”然后在“setsid”之后设置“ioctl(controlTerm,TIOCSCTTY,1)”(获取控制终端为上一个会话并将它们设置为new)但在这种情况下我有相同的行为,第二个命令返回“-1”,errno = 9(文件号错误)。
在AIX下测试相同的代码,一切运行良好。 如何在slave伪tty实现shell的控制终端?