comparison x11fwd.c @ 9:7f77962de998

- Reworked non-channel fd handling to listener.c - More channel cleaning up
author Matt Johnston <matt@ucc.asn.au>
date Thu, 03 Jun 2004 16:45:53 +0000
parents fe6bca95afa7
children f76c9389e9e0
comparison
equal deleted inserted replaced
7:425ed5c20157 9:7f77962de998
35 #include "buffer.h" 35 #include "buffer.h"
36 36
37 #define X11BASEPORT 6000 37 #define X11BASEPORT 6000
38 #define X11BINDBASE 6010 38 #define X11BINDBASE 6010
39 39
40 static void x11accept(struct Listener* listener);
41 static void x11cleanup(struct Listener *listener);
40 static int bindport(int fd); 42 static int bindport(int fd);
41 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr); 43 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
42 44
43 /* called as a request for a session channel, sets up listening X11 */ 45 /* called as a request for a session channel, sets up listening X11 */
44 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 46 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
45 int x11req(struct ChanSess * chansess) { 47 int x11req(struct ChanSess * chansess) {
46 48
49 int fd;
50
47 /* we already have an x11 connection */ 51 /* we already have an x11 connection */
48 if (chansess->x11fd != -1) { 52 if (chansess->x11listener != NULL) {
49 return DROPBEAR_FAILURE; 53 return DROPBEAR_FAILURE;
50 } 54 }
51 55
52 chansess->x11singleconn = buf_getbyte(ses.payload); 56 chansess->x11singleconn = buf_getbyte(ses.payload);
53 chansess->x11authprot = buf_getstring(ses.payload, NULL); 57 chansess->x11authprot = buf_getstring(ses.payload, NULL);
54 chansess->x11authcookie = buf_getstring(ses.payload, NULL); 58 chansess->x11authcookie = buf_getstring(ses.payload, NULL);
55 chansess->x11screennum = buf_getint(ses.payload); 59 chansess->x11screennum = buf_getint(ses.payload);
56 60
57 /* create listening socket */ 61 /* create listening socket */
58 chansess->x11fd = socket(PF_INET, SOCK_STREAM, 0); 62 fd = socket(PF_INET, SOCK_STREAM, 0);
59 if (chansess->x11fd < 0) { 63 if (fd < 0) {
60 goto fail; 64 goto fail;
61 } 65 }
62 66
63 /* allocate port and bind */ 67 /* allocate port and bind */
64 chansess->x11port = bindport(chansess->x11fd); 68 chansess->x11port = bindport(fd);
65 if (chansess->x11port < 0) { 69 if (chansess->x11port < 0) {
66 goto fail; 70 goto fail;
67 } 71 }
68 72
69 /* listen */ 73 /* listen */
70 if (listen(chansess->x11fd, 20) < 0) { 74 if (listen(fd, 20) < 0) {
71 goto fail; 75 goto fail;
72 } 76 }
73 77
74 /* set non-blocking */ 78 /* set non-blocking */
75 if (fcntl(chansess->x11fd, F_SETFL, O_NONBLOCK) < 0) { 79 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
76 goto fail; 80 goto fail;
77 } 81 }
78 82
79 /* channel.c's channel fd code will handle the socket now */ 83 /* listener code will handle the socket now.
80 84 * No cleanup handler needed, since listener_remove only happens
81 /* set the maxfd so that select() loop will notice it */ 85 * from our cleanup anyway */
82 ses.maxfd = MAX(ses.maxfd, chansess->x11fd); 86 chansess->x11listener = new_listener( fd, 0, chansess, x11accept, NULL);
87 if (chansess->x11listener == NULL) {
88 goto fail;
89 }
83 90
84 return DROPBEAR_SUCCESS; 91 return DROPBEAR_SUCCESS;
85 92
86 fail: 93 fail:
87 /* cleanup */ 94 /* cleanup */
88 x11cleanup(chansess); 95 m_free(chansess->x11authprot);
96 m_free(chansess->x11authcookie);
97 close(fd);
89 98
90 return DROPBEAR_FAILURE; 99 return DROPBEAR_FAILURE;
91 } 100 }
92 101
93 /* accepts a new X11 socket */ 102 /* accepts a new X11 socket */
94 /* returns DROPBEAR_FAILURE or DROPBEAR_SUCCESS */ 103 /* returns DROPBEAR_FAILURE or DROPBEAR_SUCCESS */
95 int x11accept(struct ChanSess * chansess) { 104 static void x11accept(struct Listener* listener) {
96 105
97 int fd; 106 int fd;
98 struct sockaddr_in addr; 107 struct sockaddr_in addr;
99 int len; 108 int len;
109 int ret;
100 110
101 len = sizeof(addr); 111 len = sizeof(addr);
102 112
103 fd = accept(chansess->x11fd, (struct sockaddr*)&addr, &len); 113 fd = accept(listener->sock, (struct sockaddr*)&addr, &len);
104 if (fd < 0) { 114 if (fd < 0) {
105 return DROPBEAR_FAILURE; 115 return;
106 } 116 }
107 117
108 /* if single-connection we close it up */ 118 /* if single-connection we close it up */
109 if (chansess->x11singleconn) { 119 if (((struct ChanSess *)(listener->typedata))->x11singleconn) {
110 x11cleanup(chansess); 120 x11cleanup(listener);
111 } 121 }
112 122
113 return send_msg_channel_open_x11(fd, &addr); 123 ret = send_msg_channel_open_x11(fd, &addr);
124 if (ret == DROPBEAR_FAILURE) {
125 close(fd);
126 }
114 } 127 }
115 128
116 /* This is called after switching to the user, and sets up the xauth 129 /* This is called after switching to the user, and sets up the xauth
117 * and environment variables. */ 130 * and environment variables. */
118 void x11setauth(struct ChanSess *chansess) { 131 void x11setauth(struct ChanSess *chansess) {
119 132
120 char display[20]; /* space for "localhost:12345.123" */ 133 char display[20]; /* space for "localhost:12345.123" */
121 FILE * authprog; 134 FILE * authprog;
122 int val; 135 int val;
123 136
124 if (chansess->x11fd == -1) { 137 if (chansess->x11listener == NULL) {
125 return; 138 return;
126 } 139 }
127 140
128 /* create the DISPLAY string */ 141 /* create the DISPLAY string */
129 val = snprintf(display, sizeof(display), "localhost:%d.%d", 142 val = snprintf(display, sizeof(display), "localhost:%d.%d",
152 } else { 165 } else {
153 fprintf(stderr, "Failed to run %s\n", XAUTH_COMMAND); 166 fprintf(stderr, "Failed to run %s\n", XAUTH_COMMAND);
154 } 167 }
155 } 168 }
156 169
157 void x11cleanup(struct ChanSess * chansess) { 170 static void x11cleanup(struct Listener *listener) {
158 171
159 if (chansess->x11fd == -1) { 172 struct ChanSess *chansess = (struct ChanSess*)listener->typedata;
160 return;
161 }
162 173
163 m_free(chansess->x11authprot); 174 m_free(chansess->x11authprot);
164 m_free(chansess->x11authcookie); 175 m_free(chansess->x11authcookie);
165 close(chansess->x11fd); 176 remove_listener(listener);
166 chansess->x11fd = -1; 177 chansess->x11listener = NULL;
167 } 178 }
179
180 static const struct ChanType chan_x11 = {
181 0, /* sepfds */
182 "x11",
183 NULL, /* inithandler */
184 NULL, /* checkclose */
185 NULL, /* reqhandler */
186 NULL /* closehandler */
187 };
188
168 189
169 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr) { 190 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr) {
170 191
171 char* ipstring; 192 char* ipstring;
172 193
173 if (send_msg_channel_open_init(fd, CHANNEL_ID_X11, "x11") 194 if (send_msg_channel_open_init(fd, &chan_x11) == DROPBEAR_SUCCESS) {
174 == DROPBEAR_SUCCESS) {
175 ipstring = inet_ntoa(addr->sin_addr); 195 ipstring = inet_ntoa(addr->sin_addr);
176 buf_putstring(ses.writepayload, ipstring, strlen(ipstring)); 196 buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
177 buf_putint(ses.writepayload, addr->sin_port); 197 buf_putint(ses.writepayload, addr->sin_port);
178 198
179 encrypt_packet(); 199 encrypt_packet();