comparison src/proxy.c @ 1252:46c09828e929

[gaim-migrate @ 1262] still need to do buddy.c, conversation.c, dialogs.c, prefs.c. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Wed, 13 Dec 2000 22:12:02 +0000
parents 56c7ceb986a8
children 153eb28ea454
comparison
equal deleted inserted replaced
1251:2d12541cedb1 1252:46c09828e929
37 #include <gtk/gtk.h> 37 #include <gtk/gtk.h>
38 #include "gaim.h" 38 #include "gaim.h"
39 #include "proxy.h" 39 #include "proxy.h"
40 40
41 /* this code is borrowed from cvs 1.10 */ 41 /* this code is borrowed from cvs 1.10 */
42 static int proxy_recv_line (int sock, char **resultp) 42 static int proxy_recv_line(int sock, char **resultp)
43 { 43 {
44 int c; 44 int c;
45 char *result; 45 char *result;
46 size_t input_index = 0; 46 size_t input_index = 0;
47 size_t result_size = 80; 47 size_t result_size = 80;
48 48
49 result = g_malloc (result_size); 49 result = g_malloc(result_size);
50 50
51 while (1) 51 while (1) {
52 { 52 char ch;
53 char ch; 53 if (recv(sock, &ch, 1, 0) < 0)
54 if (recv (sock, &ch, 1, 0) < 0) 54 debug_printf("recv() error from proxy server\n");
55 fprintf (stderr, "recv() error from proxy server\n"); 55 c = ch;
56 c = ch; 56
57 57 if (c == EOF) {
58 if (c == EOF) 58 g_free(result);
59 { 59
60 g_free (result); 60 /* It's end of file. */
61 61 debug_printf("end of file from server\n");
62 /* It's end of file. */ 62 }
63 fprintf(stderr, "end of file from server\n"); 63
64 } 64 if (c == '\012')
65 65 break;
66 if (c == '\012') 66
67 break; 67 result[input_index++] = c;
68 68 while (input_index + 1 >= result_size) {
69 result[input_index++] = c; 69 result_size *= 2;
70 while (input_index + 1 >= result_size) 70 result = (char *)g_realloc(result, result_size);
71 { 71 }
72 result_size *= 2; 72 }
73 result = (char *) g_realloc (result, result_size); 73
74 } 74 if (resultp)
75 } 75 *resultp = result;
76 76
77 if (resultp) 77 /* Terminate it just for kicks, but we *can* deal with embedded NULs. */
78 *resultp = result; 78 result[input_index] = '\0';
79 79
80 /* Terminate it just for kicks, but we *can* deal with embedded NULs. */ 80 if (resultp == NULL)
81 result[input_index] = '\0'; 81 g_free(result);
82 82 return input_index;
83 if (resultp == NULL)
84 g_free (result);
85 return input_index;
86 } 83 }
87 84
88 static int proxy_connect_none(char *host, unsigned short port) 85 static int proxy_connect_none(char *host, unsigned short port)
89 { 86 {
90 struct sockaddr_in sin; 87 struct sockaddr_in sin;
91 struct hostent *hp; 88 struct hostent *hp;
92 int fd = -1; 89 int fd = -1;
93 90
94 debug_printf("connecting to %s:%d with no proxy\n", host, port); 91 debug_printf("connecting to %s:%d with no proxy\n", host, port);
95 92
96 if (!(hp = gethostbyname(host))) 93 if (!(hp = gethostbyname(host)))
97 return -1; 94 return -1;
98 95
99 memset(&sin, 0, sizeof(struct sockaddr_in)); 96 memset(&sin, 0, sizeof(struct sockaddr_in));
100 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); 97 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
101 sin.sin_family = hp->h_addrtype; 98 sin.sin_family = hp->h_addrtype;
113 } 110 }
114 111
115 #define HTTP_GOODSTRING "HTTP/1.0 200 Connection established" 112 #define HTTP_GOODSTRING "HTTP/1.0 200 Connection established"
116 #define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" 113 #define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established"
117 114
118 static int proxy_connect_http(char *host, unsigned short port, 115 static int proxy_connect_http(char *host, unsigned short port, char *proxyhost, unsigned short proxyport)
119 char *proxyhost, unsigned short proxyport)
120 { 116 {
121 struct hostent *hp; 117 struct hostent *hp;
122 struct sockaddr_in sin; 118 struct sockaddr_in sin;
123 int fd = -1; 119 int fd = -1;
124 char cmd[384]; 120 char cmd[384];
125 char *inputline; 121 char *inputline;
126 122
127 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); 123 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport);
128 124
129 if (!(hp = gethostbyname(proxyhost))) 125 if (!(hp = gethostbyname(proxyhost)))
130 return -1; 126 return -1;
131 127
132 memset(&sin, 0, sizeof(struct sockaddr_in)); 128 memset(&sin, 0, sizeof(struct sockaddr_in));
133 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); 129 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
134 sin.sin_family = hp->h_addrtype; 130 sin.sin_family = hp->h_addrtype;
142 return -1; 138 return -1;
143 } 139 }
144 140
145 snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\n\r\n\r", host, port); 141 snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\n\r\n\r", host, port);
146 142
147 if (send(fd, cmd, strlen(cmd),0) < 0) 143 if (send(fd, cmd, strlen(cmd), 0) < 0)
148 return -1; 144 return -1;
149 if (proxy_recv_line(fd, &inputline) < 0) 145 if (proxy_recv_line(fd, &inputline) < 0)
150 return -1; 146 return -1;
151 147
152 if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING) == 0) || 148 if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING) == 0) ||
153 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2) == 0)))) { 149 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2) == 0)))) {
154 while (strlen(inputline) > 1) { 150 while (strlen(inputline) > 1) {
155 free(inputline); 151 free(inputline);
156 if (proxy_recv_line(fd, &inputline) < 0) 152 if (proxy_recv_line(fd, &inputline) < 0)
157 return -1; 153 return -1;
158 } 154 }
166 162
167 return -1; 163 return -1;
168 } 164 }
169 165
170 static int proxy_connect_socks4(char *host, unsigned short port, 166 static int proxy_connect_socks4(char *host, unsigned short port,
171 char *proxyhost, unsigned short proxyport) 167 char *proxyhost, unsigned short proxyport)
172 { 168 {
173 struct sockaddr_in sin; 169 struct sockaddr_in sin;
174 unsigned char packet[12]; 170 unsigned char packet[12];
175 struct hostent *hp; 171 struct hostent *hp;
176 int fd = -1; 172 int fd = -1;
177 173
178 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); 174 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport);
179 175
180 if (!(hp = gethostbyname(proxyhost))) 176 if (!(hp = gethostbyname(proxyhost)))
181 return -1; 177 return -1;
182 178
183 memset(&sin, 0, sizeof(struct sockaddr_in)); 179 memset(&sin, 0, sizeof(struct sockaddr_in));
184 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); 180 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
185 sin.sin_family = hp->h_addrtype; 181 sin.sin_family = hp->h_addrtype;
197 if (!(hp = gethostbyname(host))) 193 if (!(hp = gethostbyname(host)))
198 return -1; 194 return -1;
199 195
200 packet[0] = 4; 196 packet[0] = 4;
201 packet[1] = 1; 197 packet[1] = 1;
202 packet[2] = (((unsigned short) htons(port)) >> 8); 198 packet[2] = (((unsigned short)htons(port)) >> 8);
203 packet[3] = (((unsigned short) htons(port)) & 0xff); 199 packet[3] = (((unsigned short)htons(port)) & 0xff);
204 packet[4] = (unsigned char) (hp->h_addr_list[0])[0]; 200 packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
205 packet[5] = (unsigned char) (hp->h_addr_list[0])[1]; 201 packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
206 packet[6] = (unsigned char) (hp->h_addr_list[0])[2]; 202 packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
207 packet[7] = (unsigned char) (hp->h_addr_list[0])[3]; 203 packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
208 packet[8] = 0; 204 packet[8] = 0;
209 if (write(fd, packet, 9) == 9) { 205 if (write(fd, packet, 9) == 9) {
210 memset(packet, 0, sizeof(packet)); 206 memset(packet, 0, sizeof(packet));
211 if (read(fd, packet, 9) >= 4 && packet[1] == 90) 207 if (read(fd, packet, 9) >= 4 && packet[1] == 90)
212 return fd; 208 return fd;
215 211
216 return -1; 212 return -1;
217 } 213 }
218 214
219 static int proxy_connect_socks5(char *host, unsigned short port, 215 static int proxy_connect_socks5(char *host, unsigned short port,
220 char *proxyhost, unsigned short proxyport) 216 char *proxyhost, unsigned short proxyport)
221 { 217 {
222 int i, fd = -1; 218 int i, fd = -1;
223 unsigned char buf[512]; 219 unsigned char buf[512];
224 struct sockaddr_in sin; 220 struct sockaddr_in sin;
225 struct hostent *hp; 221 struct hostent *hp;
226 222
227 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); 223 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport);
228 224
229 if (!(hp = gethostbyname(proxyhost))) 225 if (!(hp = gethostbyname(proxyhost)))
230 return -1; 226 return -1;
231 227
232 memset(&sin, 0, sizeof(struct sockaddr_in)); 228 memset(&sin, 0, sizeof(struct sockaddr_in));
233 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); 229 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
234 sin.sin_family = hp->h_addrtype; 230 sin.sin_family = hp->h_addrtype;
241 close(fd); 237 close(fd);
242 return -1; 238 return -1;
243 } 239 }
244 240
245 i = 0; 241 i = 0;
246 buf[0] = 0x05; /* SOCKS version 5 */ 242 buf[0] = 0x05; /* SOCKS version 5 */
247 buf[1] = 0x01; 243 buf[1] = 0x01;
248 buf[2] = 0x00; 244 buf[2] = 0x00;
249 i = 3; 245 i = 3;
250 246
251 if (write(fd, buf, i) < i) { 247 if (write(fd, buf, i) < i) {
262 close(fd); 258 close(fd);
263 return -1; 259 return -1;
264 } 260 }
265 261
266 buf[0] = 0x05; 262 buf[0] = 0x05;
267 buf[1] = 0x01; /* CONNECT */ 263 buf[1] = 0x01; /* CONNECT */
268 buf[2] = 0x00; /* reserved */ 264 buf[2] = 0x00; /* reserved */
269 buf[3] = 0x03; /* address type -- host name */ 265 buf[3] = 0x03; /* address type -- host name */
270 buf[4] = strlen(host); 266 buf[4] = strlen(host);
271 memcpy(buf+5, host, strlen(host)); 267 memcpy(buf + 5, host, strlen(host));
272 buf[5+strlen(host)] = htons(port) >> 8; 268 buf[5 + strlen(host)] = htons(port) >> 8;
273 buf[5+strlen(host)+1] = htons(port) & 0xff; 269 buf[5 + strlen(host) + 1] = htons(port) & 0xff;
274 270
275 if (write(fd, buf, (5+strlen(host)+2)) < (5+strlen(host)+2)) { 271 if (write(fd, buf, (5 + strlen(host) + 2)) < (5 + strlen(host) + 2)) {
276 close(fd); 272 close(fd);
277 return -1; 273 return -1;
278 } 274 }
279 if (read(fd, buf, 10) < 10) { 275 if (read(fd, buf, 10) < 10) {
280 close(fd); 276 close(fd);
290 286
291 int proxy_connect(char *host, int port, char *proxyhost, int proxyport, int proxytype) 287 int proxy_connect(char *host, int port, char *proxyhost, int proxyport, int proxytype)
292 { 288 {
293 if (!host || !port || (port == -1)) 289 if (!host || !port || (port == -1))
294 return -1; 290 return -1;
295 else if ((proxytype == PROXY_NONE) || 291 else if ((proxytype == PROXY_NONE) ||
296 !proxyhost || !proxyhost[0] || 292 !proxyhost || !proxyhost[0] ||
297 !proxyport || (proxyport == -1)) 293 !proxyport || (proxyport == -1)) return proxy_connect_none(host, port);
298 return proxy_connect_none(host, port);
299 else if (proxytype == PROXY_HTTP) 294 else if (proxytype == PROXY_HTTP)
300 return proxy_connect_http(host, port, proxyhost, proxyport); 295 return proxy_connect_http(host, port, proxyhost, proxyport);
301 else if (proxytype == PROXY_SOCKS4) 296 else if (proxytype == PROXY_SOCKS4)
302 return proxy_connect_socks4(host, port, proxyhost, proxyport); 297 return proxy_connect_socks4(host, port, proxyhost, proxyport);
303 else if (proxytype == PROXY_SOCKS5) 298 else if (proxytype == PROXY_SOCKS5)