comparison src/proxy.c @ 1881:a02584b98823

[gaim-migrate @ 1891] C:) committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Wed, 23 May 2001 07:59:05 +0000
parents a49ed23b3c02
children 3366311426df
comparison
equal deleted inserted replaced
1880:b8245bcce7e6 1881:a02584b98823
38 #include <errno.h> 38 #include <errno.h>
39 #include <gtk/gtk.h> 39 #include <gtk/gtk.h>
40 #include "gaim.h" 40 #include "gaim.h"
41 #include "proxy.h" 41 #include "proxy.h"
42 42
43 char proxyhost[128] = { 0 };
44 int proxyport = 0;
45 int proxytype = 0;
46 char proxyuser[128] = { 0 };
47 char proxypass[128] = { 0 };
48
43 struct PHB { 49 struct PHB {
44 GdkInputFunction func; 50 GdkInputFunction func;
45 gpointer data; 51 gpointer data;
46 char *host; 52 char *host;
47 int port; 53 int port;
48 char *user;
49 char *pass;
50 gint inpa; 54 gint inpa;
51 }; 55 };
52 56
53 static void no_one_calls(gpointer data, gint source, GdkInputCondition cond) 57 static void no_one_calls(gpointer data, gint source, GdkInputCondition cond)
54 { 58 {
155 debug_printf("Proxy says: %s\n", inputline); 159 debug_printf("Proxy says: %s\n", inputline);
156 160
157 if ((memcmp(HTTP_GOODSTRING , inputline, strlen(HTTP_GOODSTRING )) == 0) || 161 if ((memcmp(HTTP_GOODSTRING , inputline, strlen(HTTP_GOODSTRING )) == 0) ||
158 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { 162 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
159 phb->func(phb->data, source, GDK_INPUT_READ); 163 phb->func(phb->data, source, GDK_INPUT_READ);
160 if (phb->user) {
161 g_free(phb->user);
162 g_free(phb->pass);
163 }
164 g_free(phb->host); 164 g_free(phb->host);
165 g_free(phb); 165 g_free(phb);
166 return; 166 return;
167 } 167 }
168 168
169 close(source); 169 close(source);
170 phb->func(phb->data, -1, GDK_INPUT_READ); 170 phb->func(phb->data, -1, GDK_INPUT_READ);
171 if (phb->user) {
172 g_free(phb->user);
173 g_free(phb->pass);
174 }
175 g_free(phb->host); 171 g_free(phb->host);
176 g_free(phb); 172 g_free(phb);
177 return; 173 return;
178 } 174 }
179 175
187 gdk_input_remove(phb->inpa); 183 gdk_input_remove(phb->inpa);
188 len = sizeof(error); 184 len = sizeof(error);
189 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 185 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
190 close(source); 186 close(source);
191 phb->func(phb->data, -1, GDK_INPUT_READ); 187 phb->func(phb->data, -1, GDK_INPUT_READ);
192 if (phb->user) {
193 g_free(phb->user);
194 g_free(phb->pass);
195 }
196 g_free(phb->host); 188 g_free(phb->host);
197 g_free(phb); 189 g_free(phb);
198 return; 190 return;
199 } 191 }
200 fcntl(source, F_SETFL, 0); 192 fcntl(source, F_SETFL, 0);
201 193
202 g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\n", phb->host, phb->port); 194 g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\n", phb->host, phb->port);
203 if (send(source, cmd, strlen(cmd), 0) < 0) { 195 if (send(source, cmd, strlen(cmd), 0) < 0) {
204 close(source); 196 close(source);
205 phb->func(phb->data, -1, GDK_INPUT_READ); 197 phb->func(phb->data, -1, GDK_INPUT_READ);
206 if (phb->user) { 198 g_free(phb->host);
207 g_free(phb->user); 199 g_free(phb);
208 g_free(phb->pass); 200 return;
209 } 201 }
210 g_free(phb->host); 202
211 g_free(phb); 203 if (proxyuser) {
212 return;
213 }
214
215 if (phb->user) {
216 char *t1, *t2; 204 char *t1, *t2;
217 t1 = g_strdup_printf("%s:%s", phb->user, phb->pass); 205 t1 = g_strdup_printf("%s:%s", proxyuser, proxypass);
218 t2 = tobase64(t1); 206 t2 = tobase64(t1);
219 g_free(t1); 207 g_free(t1);
220 g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); 208 g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2);
221 g_free(t2); 209 g_free(t2);
222 if (send(source, cmd, strlen(cmd), 0) < 0) { 210 if (send(source, cmd, strlen(cmd), 0) < 0) {
223 close(source); 211 close(source);
224 phb->func(phb->data, -1, GDK_INPUT_READ); 212 phb->func(phb->data, -1, GDK_INPUT_READ);
225 g_free(phb->user);
226 g_free(phb->pass);
227 g_free(phb->host); 213 g_free(phb->host);
228 g_free(phb); 214 g_free(phb);
229 return; 215 return;
230 } 216 }
231 } 217 }
232 218
233 g_snprintf(cmd, sizeof(cmd), "\r\n"); 219 g_snprintf(cmd, sizeof(cmd), "\r\n");
234 if (send(source, cmd, strlen(cmd), 0) < 0) { 220 if (send(source, cmd, strlen(cmd), 0) < 0) {
235 close(source); 221 close(source);
236 phb->func(phb->data, -1, GDK_INPUT_READ); 222 phb->func(phb->data, -1, GDK_INPUT_READ);
237 if (phb->user) {
238 g_free(phb->user);
239 g_free(phb->pass);
240 }
241 g_free(phb->host); 223 g_free(phb->host);
242 g_free(phb); 224 g_free(phb);
243 return; 225 return;
244 } 226 }
245 227
246 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, http_canread, phb); 228 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, http_canread, phb);
247 } 229 }
248 230
249 static int proxy_connect_http(char *host, unsigned short port, 231 static int proxy_connect_http(char *host, unsigned short port, struct PHB *phb)
250 char *proxyhost, unsigned short proxyport,
251 char *user, char *pass,
252 struct PHB *phb)
253 { 232 {
254 struct hostent *hp; 233 struct hostent *hp;
255 struct sockaddr_in sin; 234 struct sockaddr_in sin;
256 int fd = -1; 235 int fd = -1;
257 236
272 return -1; 251 return -1;
273 } 252 }
274 253
275 phb->host = g_strdup(host); 254 phb->host = g_strdup(host);
276 phb->port = port; 255 phb->port = port;
277 if (user && pass && user[0] && pass[0]) {
278 phb->user = g_strdup(user);
279 phb->pass = g_strdup(pass);
280 }
281 256
282 fcntl(fd, F_SETFL, O_NONBLOCK); 257 fcntl(fd, F_SETFL, O_NONBLOCK);
283 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 258 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
284 if ((errno == EINPROGRESS) || (errno == EINTR)) { 259 if ((errno == EINPROGRESS) || (errno == EINTR)) {
285 debug_printf("Connect would have blocked\n"); 260 debug_printf("Connect would have blocked\n");
286 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, http_canwrite, phb); 261 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, http_canwrite, phb);
287 } else { 262 } else {
288 close(fd); 263 close(fd);
289 if (phb->user) {
290 g_free(phb->user);
291 g_free(phb->pass);
292 }
293 g_free(phb->host); 264 g_free(phb->host);
294 g_free(phb); 265 g_free(phb);
295 return -1; 266 return -1;
296 } 267 }
297 } else { 268 } else {
298 int len, error = ETIMEDOUT; 269 int len, error = ETIMEDOUT;
299 debug_printf("Connect didn't block\n"); 270 debug_printf("Connect didn't block\n");
300 len = sizeof(error); 271 len = sizeof(error);
301 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 272 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
302 close(fd); 273 close(fd);
303 if (phb->user) {
304 g_free(phb->user);
305 g_free(phb->pass);
306 }
307 g_free(phb->host); 274 g_free(phb->host);
308 g_free(phb); 275 g_free(phb);
309 return -1; 276 return -1;
310 } 277 }
311 fcntl(fd, F_SETFL, 0); 278 fcntl(fd, F_SETFL, 0);
382 } 349 }
383 350
384 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s4_canread, phb); 351 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s4_canread, phb);
385 } 352 }
386 353
387 static int proxy_connect_socks4(char *host, unsigned short port, 354 static int proxy_connect_socks4(char *host, unsigned short port, struct PHB *phb)
388 char *proxyhost, unsigned short proxyport,
389 struct PHB *phb)
390 { 355 {
391 struct sockaddr_in sin; 356 struct sockaddr_in sin;
392 struct hostent *hp; 357 struct hostent *hp;
393 int fd = -1; 358 int fd = -1;
394 359
487 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; 452 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff;
488 453
489 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 454 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
490 close(source); 455 close(source);
491 phb->func(phb->data, -1, GDK_INPUT_READ); 456 phb->func(phb->data, -1, GDK_INPUT_READ);
492 if (phb->user) {
493 g_free(phb->user);
494 g_free(phb->pass);
495 }
496 g_free(phb->host); 457 g_free(phb->host);
497 g_free(phb); 458 g_free(phb);
498 return; 459 return;
499 } 460 }
500 461
510 debug_printf("got auth response\n"); 471 debug_printf("got auth response\n");
511 472
512 if (read(source, buf, 2) < 2) { 473 if (read(source, buf, 2) < 2) {
513 close(source); 474 close(source);
514 phb->func(phb->data, -1, GDK_INPUT_READ); 475 phb->func(phb->data, -1, GDK_INPUT_READ);
515 if (phb->user) {
516 g_free(phb->user);
517 g_free(phb->pass);
518 }
519 g_free(phb->host); 476 g_free(phb->host);
520 g_free(phb); 477 g_free(phb);
521 return; 478 return;
522 } 479 }
523 480
524 if ((buf[0] != 0x01) || (buf[1] == 0x00)) { 481 if ((buf[0] != 0x01) || (buf[1] == 0x00)) {
525 close(source); 482 close(source);
526 phb->func(phb->data, -1, GDK_INPUT_READ); 483 phb->func(phb->data, -1, GDK_INPUT_READ);
527 if (phb->user) {
528 g_free(phb->user);
529 g_free(phb->pass);
530 }
531 g_free(phb->host); 484 g_free(phb->host);
532 g_free(phb); 485 g_free(phb);
533 return; 486 return;
534 } 487 }
535 488
545 debug_printf("able to read\n"); 498 debug_printf("able to read\n");
546 499
547 if (read(source, buf, 2) < 2) { 500 if (read(source, buf, 2) < 2) {
548 close(source); 501 close(source);
549 phb->func(phb->data, -1, GDK_INPUT_READ); 502 phb->func(phb->data, -1, GDK_INPUT_READ);
550 if (phb->user) {
551 g_free(phb->user);
552 g_free(phb->pass);
553 }
554 g_free(phb->host); 503 g_free(phb->host);
555 g_free(phb); 504 g_free(phb);
556 return; 505 return;
557 } 506 }
558 507
559 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 508 if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
560 close(source); 509 close(source);
561 phb->func(phb->data, -1, GDK_INPUT_READ); 510 phb->func(phb->data, -1, GDK_INPUT_READ);
562 if (phb->user) {
563 g_free(phb->user);
564 g_free(phb->pass);
565 }
566 g_free(phb->host); 511 g_free(phb->host);
567 g_free(phb); 512 g_free(phb);
568 return; 513 return;
569 } 514 }
570 515
571 if (buf[1] == 0x02) { 516 if (buf[1] == 0x02) {
572 unsigned int i = strlen(phb->user), j = strlen(phb->pass); 517 unsigned int i = strlen(proxyuser), j = strlen(proxypass);
573 buf[0] = 0x01; /* version 1 */ 518 buf[0] = 0x01; /* version 1 */
574 buf[1] = i; 519 buf[1] = i;
575 memcpy(buf+2, phb->user, i); 520 memcpy(buf+2, proxyuser, i);
576 buf[2+i] = j; 521 buf[2+i] = j;
577 memcpy(buf+2+i+1, phb->pass, j); 522 memcpy(buf+2+i+1, proxypass, j);
578 if (write(source, buf, 3+i+j) < 3+i+j) { 523 if (write(source, buf, 3+i+j) < 3+i+j) {
579 close(source); 524 close(source);
580 phb->func(phb->data, -1, GDK_INPUT_READ); 525 phb->func(phb->data, -1, GDK_INPUT_READ);
581 g_free(phb->user);
582 g_free(phb->pass);
583 g_free(phb->host); 526 g_free(phb->host);
584 g_free(phb); 527 g_free(phb);
585 return; 528 return;
586 } 529 }
587 530
602 gdk_input_remove(phb->inpa); 545 gdk_input_remove(phb->inpa);
603 len = sizeof(error); 546 len = sizeof(error);
604 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 547 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
605 close(source); 548 close(source);
606 phb->func(phb->data, -1, GDK_INPUT_READ); 549 phb->func(phb->data, -1, GDK_INPUT_READ);
607 if (phb->user) {
608 g_free(phb->user);
609 g_free(phb->pass);
610 }
611 g_free(phb->host); 550 g_free(phb->host);
612 g_free(phb); 551 g_free(phb);
613 return; 552 return;
614 } 553 }
615 fcntl(source, F_SETFL, 0); 554 fcntl(source, F_SETFL, 0);
616 555
617 i = 0; 556 i = 0;
618 buf[0] = 0x05; /* SOCKS version 5 */ 557 buf[0] = 0x05; /* SOCKS version 5 */
619 if (phb->user) { 558 if (proxyuser[0]) {
620 buf[1] = 0x02; /* two methods */ 559 buf[1] = 0x02; /* two methods */
621 buf[2] = 0x00; /* no authentication */ 560 buf[2] = 0x00; /* no authentication */
622 buf[3] = 0x02; /* username/password authentication */ 561 buf[3] = 0x02; /* username/password authentication */
623 i = 4; 562 i = 4;
624 } else { 563 } else {
629 568
630 if (write(source, buf, i) < i) { 569 if (write(source, buf, i) < i) {
631 debug_printf("unable to write\n"); 570 debug_printf("unable to write\n");
632 close(source); 571 close(source);
633 phb->func(phb->data, -1, GDK_INPUT_READ); 572 phb->func(phb->data, -1, GDK_INPUT_READ);
634 if (phb->user) {
635 g_free(phb->user);
636 g_free(phb->pass);
637 }
638 g_free(phb->host); 573 g_free(phb->host);
639 g_free(phb); 574 g_free(phb);
640 return; 575 return;
641 } 576 }
642 577
643 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread, phb); 578 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread, phb);
644 } 579 }
645 580
646 static int proxy_connect_socks5(char *host, unsigned short port, 581 static int proxy_connect_socks5(char *host, unsigned short port, struct PHB *phb)
647 char *proxyhost, unsigned short proxyport,
648 char *user, char *pass,
649 struct PHB *phb)
650 { 582 {
651 int fd = -1; 583 int fd = -1;
652 struct sockaddr_in sin; 584 struct sockaddr_in sin;
653 struct hostent *hp; 585 struct hostent *hp;
654 586
667 if ((fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { 599 if ((fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
668 g_free(phb); 600 g_free(phb);
669 return -1; 601 return -1;
670 } 602 }
671 603
672 if (user && pass && user[0] && pass[0]) {
673 phb->user = g_strdup(user);
674 phb->pass = g_strdup(pass);
675 }
676 phb->host = g_strdup(host); 604 phb->host = g_strdup(host);
677 phb->port = port; 605 phb->port = port;
678 606
679 fcntl(fd, F_SETFL, O_NONBLOCK); 607 fcntl(fd, F_SETFL, O_NONBLOCK);
680 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 608 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
681 if ((errno == EINPROGRESS) || (errno == EINTR)) { 609 if ((errno == EINPROGRESS) || (errno == EINTR)) {
682 debug_printf("Connect would have blocked\n"); 610 debug_printf("Connect would have blocked\n");
683 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, s5_canwrite, phb); 611 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, s5_canwrite, phb);
684 } else { 612 } else {
685 close(fd); 613 close(fd);
686 if (phb->user) {
687 g_free(phb->user);
688 g_free(phb->pass);
689 }
690 g_free(phb->host); 614 g_free(phb->host);
691 g_free(phb); 615 g_free(phb);
692 return -1; 616 return -1;
693 } 617 }
694 } else { 618 } else {
695 int len, error = ETIMEDOUT; 619 int len, error = ETIMEDOUT;
696 debug_printf("Connect didn't block\n"); 620 debug_printf("Connect didn't block\n");
697 len = sizeof(error); 621 len = sizeof(error);
698 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 622 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
699 close(fd); 623 close(fd);
700 if (phb->user) {
701 g_free(phb->user);
702 g_free(phb->pass);
703 }
704 g_free(phb->host); 624 g_free(phb->host);
705 g_free(phb); 625 g_free(phb);
706 return -1; 626 return -1;
707 } 627 }
708 fcntl(fd, F_SETFL, 0); 628 fcntl(fd, F_SETFL, 0);
710 } 630 }
711 631
712 return fd; 632 return fd;
713 } 633 }
714 634
715 int proxy_connect(char *host, int port, 635 int proxy_connect(char *host, int port, GdkInputFunction func, gpointer data)
716 char *proxyhost, int proxyport, int proxytype,
717 char *user, char *pass,
718 GdkInputFunction func, gpointer data)
719 { 636 {
720 struct PHB *phb = g_new0(struct PHB, 1); 637 struct PHB *phb = g_new0(struct PHB, 1);
721 phb->func = func; 638 phb->func = func;
722 phb->data = data; 639 phb->data = data;
723 640
729 if ((proxytype == PROXY_NONE) || 646 if ((proxytype == PROXY_NONE) ||
730 !proxyhost || !proxyhost[0] || 647 !proxyhost || !proxyhost[0] ||
731 !proxyport || (proxyport == -1)) 648 !proxyport || (proxyport == -1))
732 return proxy_connect_none(host, port, phb); 649 return proxy_connect_none(host, port, phb);
733 else if (proxytype == PROXY_HTTP) 650 else if (proxytype == PROXY_HTTP)
734 return proxy_connect_http(host, port, proxyhost, proxyport, user, pass, phb); 651 return proxy_connect_http(host, port, phb);
735 else if (proxytype == PROXY_SOCKS4) 652 else if (proxytype == PROXY_SOCKS4)
736 return proxy_connect_socks4(host, port, proxyhost, proxyport, phb); 653 return proxy_connect_socks4(host, port, phb);
737 else if (proxytype == PROXY_SOCKS5) 654 else if (proxytype == PROXY_SOCKS5)
738 return proxy_connect_socks5(host, port, proxyhost, proxyport, user, pass, phb); 655 return proxy_connect_socks5(host, port, phb);
739 656
740 g_free(phb); 657 g_free(phb);
741 return -1; 658 return -1;
742 } 659 }