Mercurial > pidgin.yaz
comparison src/proxy.c @ 4634:d19872836812
[gaim-migrate @ 4941]
This will let you set up different proxy settings for different accounts.
Mainly useful to the corporate users that need to connect to an internal
jabber server, and still want to connect to "external" stuff through a
proxy, or something along those lines. I'm sure someone will come up with
another use for it.
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Sun, 02 Mar 2003 18:48:02 +0000 |
parents | 6ed914a991ef |
children | 4bb99cdfd837 |
comparison
equal
deleted
inserted
replaced
4633:812148fb2e2f | 4634:d19872836812 |
---|---|
53 #endif | 53 #endif |
54 | 54 |
55 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) | 55 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) |
56 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) | 56 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) |
57 | 57 |
58 char proxyhost[128] = { 0 }; | 58 struct gaim_proxy_info global_proxy_info; |
59 int proxyport = 0; | |
60 proxytype_t proxytype = PROXY_NONE; | |
61 char proxyuser[128] = { 0 }; | |
62 char proxypass[128] = { 0 }; | |
63 | 59 |
64 struct PHB { | 60 struct PHB { |
65 GaimInputFunction func; | 61 GaimInputFunction func; |
66 gpointer data; | 62 gpointer data; |
67 char *host; | 63 char *host; |
68 int port; | 64 int port; |
69 gint inpa; | 65 gint inpa; |
70 proxytype_t proxytype; | 66 struct gaim_proxy_info *gpi; |
71 }; | 67 }; |
72 | 68 |
73 typedef struct _GaimIOClosure { | 69 typedef struct _GaimIOClosure { |
74 GaimInputFunction function; | 70 GaimInputFunction function; |
75 guint result; | 71 guint result; |
726 return; | 722 return; |
727 } | 723 } |
728 request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, | 724 request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, |
729 phb->host, phb->port); | 725 phb->host, phb->port); |
730 | 726 |
731 if (proxyuser) { | 727 if (phb->gpi->proxyuser) { |
732 char *t1, *t2; | 728 char *t1, *t2; |
733 t1 = g_strdup_printf("%s:%s", proxyuser, proxypass); | 729 t1 = g_strdup_printf("%s:%s", phb->gpi->proxyuser, phb->gpi->proxypass); |
734 t2 = tobase64(t1); | 730 t2 = tobase64(t1); |
735 g_free(t1); | 731 g_free(t1); |
736 g_return_if_fail(request_len < sizeof(request)); | 732 g_return_if_fail(request_len < sizeof(request)); |
737 request_len += g_snprintf(request + request_len, sizeof(request) - request_len, "Proxy-Authorization: Basic %s\r\n", t2); | 733 request_len += g_snprintf(request + request_len, sizeof(request) - request_len, "Proxy-Authorization: Basic %s\r\n", t2); |
738 g_free(t2); | 734 g_free(t2); |
755 | 751 |
756 static int proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) | 752 static int proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
757 { | 753 { |
758 int fd = -1; | 754 int fd = -1; |
759 | 755 |
760 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", phb->host, phb->port, proxyhost, proxyport); | 756 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", phb->host, phb->port, phb->gpi->proxyhost, phb->gpi->proxyport); |
761 | 757 |
762 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { | 758 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
763 g_free(phb->host); | 759 g_free(phb->host); |
764 g_free(phb); | 760 g_free(phb); |
765 return -1; | 761 return -1; |
871 | 867 |
872 static int proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) | 868 static int proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
873 { | 869 { |
874 int fd = -1; | 870 int fd = -1; |
875 | 871 |
876 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", phb->host, phb->port, proxyhost, proxyport); | 872 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", phb->host, phb->port, phb->gpi->proxyhost, phb->gpi->proxyport); |
877 | 873 |
878 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { | 874 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
879 g_free(phb->host); | 875 g_free(phb->host); |
880 g_free(phb); | 876 g_free(phb); |
881 return -1; | 877 return -1; |
1018 g_free(phb); | 1014 g_free(phb); |
1019 return; | 1015 return; |
1020 } | 1016 } |
1021 | 1017 |
1022 if (buf[1] == 0x02) { | 1018 if (buf[1] == 0x02) { |
1023 unsigned int i = strlen(proxyuser), j = strlen(proxypass); | 1019 unsigned int i = strlen(phb->gpi->proxyuser), j = strlen(phb->gpi->proxypass); |
1024 buf[0] = 0x01; /* version 1 */ | 1020 buf[0] = 0x01; /* version 1 */ |
1025 buf[1] = i; | 1021 buf[1] = i; |
1026 memcpy(buf + 2, proxyuser, i); | 1022 memcpy(buf + 2, phb->gpi->proxyuser, i); |
1027 buf[2 + i] = j; | 1023 buf[2 + i] = j; |
1028 memcpy(buf + 2 + i + 1, proxypass, j); | 1024 memcpy(buf + 2 + i + 1, phb->gpi->proxypass, j); |
1029 | 1025 |
1030 if (write(source, buf, 3 + i + j) < 3 + i + j) { | 1026 if (write(source, buf, 3 + i + j) < 3 + i + j) { |
1031 close(source); | 1027 close(source); |
1032 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1028 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1033 g_free(phb->host); | 1029 g_free(phb->host); |
1062 } | 1058 } |
1063 fcntl(source, F_SETFL, 0); | 1059 fcntl(source, F_SETFL, 0); |
1064 | 1060 |
1065 i = 0; | 1061 i = 0; |
1066 buf[0] = 0x05; /* SOCKS version 5 */ | 1062 buf[0] = 0x05; /* SOCKS version 5 */ |
1067 if (proxyuser[0]) { | 1063 if (phb->gpi->proxyuser[0]) { |
1068 buf[1] = 0x02; /* two methods */ | 1064 buf[1] = 0x02; /* two methods */ |
1069 buf[2] = 0x00; /* no authentication */ | 1065 buf[2] = 0x00; /* no authentication */ |
1070 buf[3] = 0x02; /* username/password authentication */ | 1066 buf[3] = 0x02; /* username/password authentication */ |
1071 i = 4; | 1067 i = 4; |
1072 } else { | 1068 } else { |
1089 | 1085 |
1090 static int proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) | 1086 static int proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) |
1091 { | 1087 { |
1092 int fd = -1; | 1088 int fd = -1; |
1093 | 1089 |
1094 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", phb->host, phb->port, proxyhost, proxyport); | 1090 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", phb->host, phb->port, phb->gpi->proxyhost, phb->gpi->proxyport); |
1095 | 1091 |
1096 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { | 1092 if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { |
1097 g_free(phb->host); | 1093 g_free(phb->host); |
1098 g_free(phb); | 1094 g_free(phb); |
1099 return -1; | 1095 return -1; |
1130 } | 1126 } |
1131 | 1127 |
1132 static void connection_host_resolved(struct sockaddr *addr, size_t addrlen, gpointer data, const char *error_message) | 1128 static void connection_host_resolved(struct sockaddr *addr, size_t addrlen, gpointer data, const char *error_message) |
1133 { | 1129 { |
1134 struct PHB *phb = (struct PHB*)data; | 1130 struct PHB *phb = (struct PHB*)data; |
1135 | 1131 |
1136 if(!addr) | 1132 if(!addr) |
1137 { | 1133 { |
1138 phb->func(phb->data, -1, GAIM_INPUT_READ); | 1134 phb->func(phb->data, -1, GAIM_INPUT_READ); |
1139 return; | 1135 return; |
1140 } | 1136 } |
1141 | 1137 |
1142 switch(phb->proxytype) | 1138 switch(phb->gpi->proxytype) |
1143 { | 1139 { |
1144 case PROXY_NONE: | 1140 case PROXY_NONE: |
1145 proxy_connect_none(phb, addr, addrlen); | 1141 proxy_connect_none(phb, addr, addrlen); |
1146 break; | 1142 break; |
1147 case PROXY_HTTP: | 1143 case PROXY_HTTP: |
1155 break; | 1151 break; |
1156 } | 1152 } |
1157 } | 1153 } |
1158 | 1154 |
1159 int | 1155 int |
1160 proxy_connect(char *host, int port, GaimInputFunction func, gpointer data) | 1156 proxy_connect(struct gaim_account *account, char *host, int port, GaimInputFunction func, gpointer data) |
1161 { | 1157 { |
1162 char *connecthost = host; | 1158 char *connecthost = host; |
1163 int connectport = port; | 1159 int connectport = port; |
1164 struct PHB *phb = g_new0(struct PHB, 1); | 1160 struct PHB *phb = g_new0(struct PHB, 1); |
1161 if(!account || !account->gpi) | |
1162 phb->gpi = &global_proxy_info; | |
1163 else | |
1164 phb->gpi = account->gpi; | |
1165 phb->func = func; | 1165 phb->func = func; |
1166 phb->data = data; | 1166 phb->data = data; |
1167 phb->host = g_strdup(host); | 1167 phb->host = g_strdup(host); |
1168 phb->port = port; | 1168 phb->port = port; |
1169 phb->proxytype = proxytype; | |
1170 | 1169 |
1171 if (!host || !port || (port == -1) || !func) { | 1170 if (!host || !port || (port == -1) || !func) { |
1172 if(host) | 1171 if(host) |
1173 g_free(phb->host); | 1172 g_free(phb->host); |
1174 g_free(phb); | 1173 g_free(phb); |
1175 return -1; | 1174 return -1; |
1176 } | 1175 } |
1177 | 1176 |
1178 if ((phb->proxytype!=PROXY_NONE) && (!proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1))) | 1177 if ((phb->gpi->proxytype!=PROXY_NONE) && (!phb->gpi->proxyhost || !phb->gpi->proxyhost[0] || !phb->gpi->proxyport || (phb->gpi->proxyport == -1))) |
1179 phb->proxytype=PROXY_NONE; | 1178 phb->gpi->proxytype=PROXY_NONE; |
1180 | 1179 |
1181 switch(phb->proxytype) | 1180 switch(phb->gpi->proxytype) |
1182 { | 1181 { |
1183 case PROXY_NONE: | 1182 case PROXY_NONE: |
1184 break; | 1183 break; |
1185 case PROXY_HTTP: | 1184 case PROXY_HTTP: |
1186 case PROXY_SOCKS4: | 1185 case PROXY_SOCKS4: |
1187 case PROXY_SOCKS5: | 1186 case PROXY_SOCKS5: |
1188 connecthost=proxyhost; | 1187 connecthost=phb->gpi->proxyhost; |
1189 connectport=proxyport; | 1188 connectport=phb->gpi->proxyport; |
1190 break; | 1189 break; |
1191 default: | 1190 default: |
1192 g_free(phb->host); | 1191 g_free(phb->host); |
1193 g_free(phb); | 1192 g_free(phb); |
1194 return -1; | 1193 return -1; |