comparison src/proxy.c @ 1844:9845deede1e9

[gaim-migrate @ 1854] i think this should work. i don't know for sure though. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sat, 12 May 2001 08:48:06 +0000
parents 4dbd8533d209
children a49ed23b3c02
comparison
equal deleted inserted replaced
1843:4dbd8533d209 1844:9845deede1e9
456 g_free(phb->host); 456 g_free(phb->host);
457 g_free(phb); 457 g_free(phb);
458 return; 458 return;
459 } 459 }
460 460
461 static void s5_canread(gpointer data, gint source, GdkInputCondition cond) 461 static void s5_sendconnect(gpointer data, gint source)
462 { 462 {
463 unsigned char buf[512]; 463 unsigned char buf[512];
464 struct PHB *phb = data; 464 struct PHB *phb = data;
465 int hlen = strlen(phb->host); 465 int hlen = strlen(phb->host);
466
467 gdk_input_remove(phb->inpa);
468 debug_printf("able to read\n");
469
470 if (read(source, buf, 2) < 2) {
471 close(source);
472 phb->func(phb->data, -1, GDK_INPUT_READ);
473 g_free(phb->host);
474 g_free(phb);
475 return;
476 }
477
478 if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
479 close(source);
480 phb->func(phb->data, -1, GDK_INPUT_READ);
481 g_free(phb->host);
482 g_free(phb);
483 return;
484 }
485 466
486 buf[0] = 0x05; 467 buf[0] = 0x05;
487 buf[1] = 0x01; /* CONNECT */ 468 buf[1] = 0x01; /* CONNECT */
488 buf[2] = 0x00; /* reserved */ 469 buf[2] = 0x00; /* reserved */
489 buf[3] = 0x03; /* address type -- host name */ 470 buf[3] = 0x03; /* address type -- host name */
493 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; 474 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff;
494 475
495 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 476 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
496 close(source); 477 close(source);
497 phb->func(phb->data, -1, GDK_INPUT_READ); 478 phb->func(phb->data, -1, GDK_INPUT_READ);
479 if (phb->user) {
480 g_free(phb->user);
481 g_free(phb->pass);
482 }
498 g_free(phb->host); 483 g_free(phb->host);
499 g_free(phb); 484 g_free(phb);
500 return; 485 return;
501 } 486 }
502 487
503 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread_again, phb); 488 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread_again, phb);
489 }
490
491 static void s5_readauth(gpointer data, gint source, GdkInputCondition cond)
492 {
493 unsigned char buf[512];
494 struct PHB *phb = data;
495
496 gdk_input_remove(phb->inpa);
497 debug_printf("got auth response\n");
498
499 if (read(source, buf, 2) < 2) {
500 close(source);
501 phb->func(phb->data, -1, GDK_INPUT_READ);
502 if (phb->user) {
503 g_free(phb->user);
504 g_free(phb->pass);
505 }
506 g_free(phb->host);
507 g_free(phb);
508 return;
509 }
510
511 if ((buf[0] != 0x01) || (buf[1] == 0x00)) {
512 close(source);
513 phb->func(phb->data, -1, GDK_INPUT_READ);
514 if (phb->user) {
515 g_free(phb->user);
516 g_free(phb->pass);
517 }
518 g_free(phb->host);
519 g_free(phb);
520 return;
521 }
522
523 s5_sendconnect(phb, source);
524 }
525
526 static void s5_canread(gpointer data, gint source, GdkInputCondition cond)
527 {
528 unsigned char buf[512];
529 struct PHB *phb = data;
530
531 gdk_input_remove(phb->inpa);
532 debug_printf("able to read\n");
533
534 if (read(source, buf, 2) < 2) {
535 close(source);
536 phb->func(phb->data, -1, GDK_INPUT_READ);
537 if (phb->user) {
538 g_free(phb->user);
539 g_free(phb->pass);
540 }
541 g_free(phb->host);
542 g_free(phb);
543 return;
544 }
545
546 if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
547 close(source);
548 phb->func(phb->data, -1, GDK_INPUT_READ);
549 if (phb->user) {
550 g_free(phb->user);
551 g_free(phb->pass);
552 }
553 g_free(phb->host);
554 g_free(phb);
555 return;
556 }
557
558 if (buf[1] == 0x02) {
559 unsigned int i = strlen(phb->user), j = strlen(phb->pass);
560 buf[0] = 0x01; /* version 1 */
561 buf[1] = i;
562 memcpy(buf+2, phb->user, i);
563 buf[2+i] = j;
564 memcpy(buf+2+i+1, phb->pass, j);
565 if (write(source, buf, 3+i+j) < 3+i+j) {
566 close(source);
567 phb->func(phb->data, -1, GDK_INPUT_READ);
568 g_free(phb->user);
569 g_free(phb->pass);
570 g_free(phb->host);
571 g_free(phb);
572 return;
573 }
574
575 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_readauth, phb);
576 } else {
577 s5_sendconnect(phb, source);
578 }
504 } 579 }
505 580
506 static void s5_canwrite(gpointer data, gint source, GdkInputCondition cond) 581 static void s5_canwrite(gpointer data, gint source, GdkInputCondition cond)
507 { 582 {
508 unsigned char buf[512]; 583 unsigned char buf[512];
514 gdk_input_remove(phb->inpa); 589 gdk_input_remove(phb->inpa);
515 len = sizeof(error); 590 len = sizeof(error);
516 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 591 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
517 close(source); 592 close(source);
518 phb->func(phb->data, -1, GDK_INPUT_READ); 593 phb->func(phb->data, -1, GDK_INPUT_READ);
594 if (phb->user) {
595 g_free(phb->user);
596 g_free(phb->pass);
597 }
519 g_free(phb->host); 598 g_free(phb->host);
520 g_free(phb); 599 g_free(phb);
521 return; 600 return;
522 } 601 }
523 fcntl(source, F_SETFL, 0); 602 fcntl(source, F_SETFL, 0);
524 603
525 i = 0; 604 i = 0;
526 buf[0] = 0x05; /* SOCKS version 5 */ 605 buf[0] = 0x05; /* SOCKS version 5 */
527 buf[1] = 0x01; 606 if (phb->user) {
528 buf[2] = 0x00; 607 buf[1] = 0x02; /* two methods */
529 i = 3; 608 buf[2] = 0x00; /* no authentication */
609 buf[3] = 0x02; /* username/password authentication */
610 i = 4;
611 } else {
612 buf[1] = 0x01;
613 buf[2] = 0x00;
614 i = 3;
615 }
530 616
531 if (write(source, buf, i) < i) { 617 if (write(source, buf, i) < i) {
532 debug_printf("unable to write\n"); 618 debug_printf("unable to write\n");
533 close(source); 619 close(source);
534 phb->func(phb->data, -1, GDK_INPUT_READ); 620 phb->func(phb->data, -1, GDK_INPUT_READ);
621 if (phb->user) {
622 g_free(phb->user);
623 g_free(phb->pass);
624 }
535 g_free(phb->host); 625 g_free(phb->host);
536 g_free(phb); 626 g_free(phb);
537 return; 627 return;
538 } 628 }
539 629
540 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread, phb); 630 phb->inpa = gdk_input_add(source, GDK_INPUT_READ, s5_canread, phb);
541 } 631 }
542 632
543 static int proxy_connect_socks5(char *host, unsigned short port, 633 static int proxy_connect_socks5(char *host, unsigned short port,
544 char *proxyhost, unsigned short proxyport, 634 char *proxyhost, unsigned short proxyport,
635 char *user, char *pass,
545 struct PHB *phb) 636 struct PHB *phb)
546 { 637 {
547 int fd = -1; 638 int fd = -1;
548 struct sockaddr_in sin; 639 struct sockaddr_in sin;
549 struct hostent *hp; 640 struct hostent *hp;
563 if ((fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { 654 if ((fd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
564 g_free(phb); 655 g_free(phb);
565 return -1; 656 return -1;
566 } 657 }
567 658
659 if (user && pass && user[0] && pass[0]) {
660 phb->user = g_strdup(user);
661 phb->pass = g_strdup(pass);
662 }
568 phb->host = g_strdup(host); 663 phb->host = g_strdup(host);
569 phb->port = port; 664 phb->port = port;
570 665
571 fcntl(fd, F_SETFL, O_NONBLOCK); 666 fcntl(fd, F_SETFL, O_NONBLOCK);
572 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 667 if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
573 if ((errno == EINPROGRESS) || (errno == EINTR)) { 668 if ((errno == EINPROGRESS) || (errno == EINTR)) {
574 debug_printf("Connect would have blocked\n"); 669 debug_printf("Connect would have blocked\n");
575 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, s5_canwrite, phb); 670 phb->inpa = gdk_input_add(fd, GDK_INPUT_WRITE, s5_canwrite, phb);
576 } else { 671 } else {
577 close(fd); 672 close(fd);
673 if (phb->user) {
674 g_free(phb->user);
675 g_free(phb->pass);
676 }
578 g_free(phb->host); 677 g_free(phb->host);
579 g_free(phb); 678 g_free(phb);
580 return -1; 679 return -1;
581 } 680 }
582 } else { 681 } else {
583 int len, error = ETIMEDOUT; 682 int len, error = ETIMEDOUT;
584 debug_printf("Connect didn't block\n"); 683 debug_printf("Connect didn't block\n");
585 len = sizeof(error); 684 len = sizeof(error);
586 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 685 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
587 close(fd); 686 close(fd);
687 if (phb->user) {
688 g_free(phb->user);
689 g_free(phb->pass);
690 }
588 g_free(phb->host); 691 g_free(phb->host);
589 g_free(phb); 692 g_free(phb);
590 return -1; 693 return -1;
591 } 694 }
592 fcntl(fd, F_SETFL, 0); 695 fcntl(fd, F_SETFL, 0);
617 else if (proxytype == PROXY_HTTP) 720 else if (proxytype == PROXY_HTTP)
618 return proxy_connect_http(host, port, proxyhost, proxyport, user, pass, phb); 721 return proxy_connect_http(host, port, proxyhost, proxyport, user, pass, phb);
619 else if (proxytype == PROXY_SOCKS4) 722 else if (proxytype == PROXY_SOCKS4)
620 return proxy_connect_socks4(host, port, proxyhost, proxyport, phb); 723 return proxy_connect_socks4(host, port, proxyhost, proxyport, phb);
621 else if (proxytype == PROXY_SOCKS5) 724 else if (proxytype == PROXY_SOCKS5)
622 return proxy_connect_socks5(host, port, proxyhost, proxyport, phb); 725 return proxy_connect_socks5(host, port, proxyhost, proxyport, user, pass, phb);
623 726
624 g_free(phb); 727 g_free(phb);
625 return -1; 728 return -1;
626 } 729 }